关于属性,我们声明的时候会使用Strong与Weak。但是二者在使用的时候有什么区别呢。
1、在使用xib 或者SB 拖控件的时候我们都会看到系统帮我们声明的是:@property (weak, nonatomic) IBOutlet UILabel *lalbel;
,首先这个控件是用weak来声明的。所以一旦执行了[self.lalbel removeFromSuperview];
lalbel的地址为nil,只要在使用该控件过程中,没有执行removeFromSuperview
,该控件会一直存在在内存里,不会被释放。
当我们用使用代码来声明一个weak属性时,
系统会自动识别,在分配好内存好因为没有强引用,只有weak引用,会直接释放掉,所以此刻打印self.label 是nil。
我们需要这样做:
UILabel *lable =[[UILabel alloc]init];
self.label = lable;
此刻 打印self.label 是有地址的。
但是 如果该控件没有被加到父视图中,出了该作用域,依然是没有地址的。
2、 使用strong 来修饰,不管有没有加到父视图里,该控件的地址会一直存在。因为它一直被 该ViewController强引用。只有ViewController 执行了delloc 之后,才会释放。
3、weak 与assign 的区别:
- assign 可以修饰基本数据类型和对象,但是修饰对象后,对象被释放,指针不会被释放。对象释放后访问该指针会显示
[UILabel retain]: message sent to deallocated instance 0x7fc0eec0c1d0 (lldb)
对已经dealloc 的对象进行了访问 - weak 只能修饰对象 ,对象释放后,指针为nil,对nil 访问不会造成崩溃。代理声明使用weak。
总结:
如果要严格控制内存管理,对于不常用或者中间可能不需要被释放内存的属性,我们使用weak来修饰,但是要严格注意是不是被父视图所引用。
如果不是那么严格,所有的控件属性通过strong来修饰,地址就会永远存在,不用担心突然被释放的问题。
如果控件在使用过程中一直存在,那么使用strong即可。如果控件在使用过程中会被移除,那么使用weak,可以节省内存。
retain 与strong的区别
声明属性时用strong或者retain效果是一样的(貌似更多开发者更倾向于用strong)。不过在声明Block时,使用strong和retain会有截然不同的效果。strong会等于copy,而retain竟然等于assign!
当然定义Block还是应该用copy),因为非ARC下不copy的Block会在栈中,ARC中的Block都会在堆上的。
参考文章# iOS的属性声明:retain和strong的区别