美文网首页
weak和strong

weak和strong

作者: 飞天猪Pony | 来源:发表于2018-06-29 14:33 被阅读48次

    注:ARC是苹果为了简化程序员对内存的管理,推出的一套内存管理机制,对象的申请和释放工作会在运行时,由编译器自动添加retain和release。

    ARC原理

    只要有一个变量指向对象,对象就会保持在内存中。
    当指针指向新值,或者指针不再存在时,相关联的对象就会自动释放。这条规则对于实例变量、synthesize属性、局部变量都是适用的

    weak和strong在ARC下的使用

    weak相当于assign,不会造成引用计数加1;
    而strong相当于retain,会造成引用计数加1。

    什么时候使用weak,什么时候使用strong,什么时候使用copy?

    1、弱指针weak

    在使用 sb 或者 xib 给控件拖线的时候,为什么拖出来的先属性都是用 weak 修饰呢?

    @property (weak,  nonatomic) IBOutlet UILabel *label;
    

    原来在xib中创建或放置控件的时候,已经形成了这种引用关系

    UIViewController->UIView->subView->UILabel
    

    由于在向 xib 或者 sb 里面添加控件的时候,添加的子视图是添加到了跟视图 View 上面, 而 控制器 Controller 对其根视图 View 默认是强引用的,当我们的子控件添加到 view 上面的时候,[self.view addSubView:label]这个方法会对添加的控件进行强引用,如果在用 strong 对添加的子控件进行修饰的话,相当于有两条强指针对子控件进行强引用, 为了避免这种情况,所以用 weak 修饰。

    注意:
    1. addSubView 默认对其 subView 进行了强引用
    2.在纯手写代码实现界面布局时,如果通过懒加载处理界面控件,需要使用strong强指针
    

    除此之外,我们在开发的时候用的代理 也是用 weak 进行修饰的,其目的是为了防止控件的循环引用

    @property (nonatomic, weak) id<PersonDelegate> delegate;
    
    2、强指针strong

    strong修饰的属性一般不会自动释放;
    在OC中,对象默认是强指针,一般控件的对象用strong来修饰(如:UIButton,UILabel),在使用懒加载定义控件的时候,一般也用strong

    @property (nonatomic, strong ) UILabel *label;
    @property (nonatomic, strong ) UIButton *btn;
    

    懒加载控件

    - (UILabel *)label
    {
         if(_label == nil)
         {
               _label = [[UILabel alloc] init];
         }
         return _label;
    }
    
    3、copy的使用

    对于 copy 的使用,网上已经有很多关于 copy 介绍, 其包括深 copy 和浅 copy, ,如果不太明白的话可以网上查一下资料

    copy 一般用来修饰 NSString 、NSArray、NSDictionary和 block
    

    懒加载

    懒加载——也称为延迟加载,即在需要的时候才加载(效率低,占用内存小)。所谓懒加载,其实就是重写getter方法。说的通俗一点,就是在开发中,当程序中需要利用的资源时。在程序启动的时候不加载资源,只有在运行当需要一些资源时,再去加载这些资源。

    我们知道iOS设备的内存有限,如果在程序在启动后就一次性加载将来会用到的所有资源,那么就有可能会耗尽iOS设备的内存。这些资源例如大量数据,图片,音频等等,所以我们在使用懒加载的时候一定要注意先判断是否已经有了,如果没有那么再去进行实例化。

    使用懒加载的好处

    1、不必将创建对象的代码全部写在viewDidLoad方法中,代码的可读性更强
    2、每个控件的getter方法中分别负责各自的实例化处理,代码彼此之间的独立性强,松耦合。且其中还进行了非空判断,防止对象被重复加载
    3、只有当真正需要资源时,再去加载,节省了内存资源,防止对象被提前创建,也防止了使用对象时对象还没被创建的问题(内存优化,如加载plist文件等耗内存的操作)。

    @property (nonatomic,strong)NSArray *dataSource;
    #pragma mark 懒加载
    -(NSArray *)dataSource
    {
        if (_dataSource == nil) {
            _dataSource = @[@"1",@"2",@"3",@"4"];
        }
        return _dataSource;
    }
    // 最后在用的时候采用self.dataSource形式方式即可
    

    循环引用问题(场景)

    1.经典:代理模式Delegate(UITableViewDelegate)

    举例:
    控制器的view强引用Tableview,而tableview的delegate又是控制器,如果下面两个代理属性用strong去修饰,就会造成循环引用问题,解决这个问题的最好办法就是两者其中之一对其弱引用就可以了(weak)。

    @property (nonatomic, weak, nullable) id <UITableViewDataSource> dataSource;
    @property (nonatomic, weak, nullable) id <UITableViewDelegate> delegate;
    

    2.block作为成员变量,而在block中又访问了self或其属性造成循环引用

    参考文章:
    https://www.jianshu.com/p/2a2e1f0849ef

    相关文章

      网友评论

          本文标题:weak和strong

          本文链接:https://www.haomeiwen.com/subject/gezoyftx.html