weak和strong

注: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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容