注: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或其属性造成循环引用
网友评论