MRC
assign
MRC下assign是属性默认的修饰符,无论是简单的数据类型,还是指向对象的指针。
// 以下两种写法等价
@property (nonatomic) NSString *name;
@property (nonatomic, assign) NSString *name;
- assign 主要用于修饰非指针类型变量(一般的基础数据,C数据类型)。比如 NSInteger,CGFloat,int,float,double,char,等等。
- assign 也可修饰对象(不建议)。当需要修饰对象类型时,MRC时代使用unsafe_unretained。当然,unsafe_unretained也可能产生野指针,所以它名字是"unsafe_”。
- assign 修饰的属性不持有对象,当其指向的对象在别处释放后,该指针变为悬挂指针也叫野指针。
unsafe_unretained
语义等同于 assign,一般用于修饰对象,也可用于修饰数据类型。当目标对象遭到销毁时,属性值不会自动清空。产生野指针。
retain
修饰的属性会持有它所指向的对象,对象的引用计数 +1,当不再需要使用该对象时需调用 release 释放。
copy
只能用于修饰对象属性,将对象赋值给 copy 属性时,一般情况下属性会持有该对象的一份拷贝。
copy 分为深拷贝和浅拷贝。对于 Foundation 中含有可变版本的对象类型,对其不可变版本的 copy 为浅拷贝,对于可变对象的 copy 为深拷贝。
深拷贝与浅拷贝
从图中我们可以了解到,浅拷贝只是拷贝了指针,并未拷贝对象本身;而深拷贝则是指针和对象本身都进行了拷贝。
- 浅拷贝:
- 深拷贝:
对于不可变对象而言,copy便是浅拷贝,而mutableCopy是深拷贝。
对于可变对象而言,copy和mutableCopy都是深拷贝。但是copy出来的对象是不可变的,而mutableCopy则是可变对象。
ARC
assign/copy/retain
同 MRC 下的语义。
strong
语义等同于 retain,体现了一种“拥有关系”。
设置新值时,setter方法会先保留新值,并释放旧值,然后再将新值设置上去。
在ARC环境下,copy和strong类似。
weak
语义等同于unsafe_unretained,体现了一种“非拥有关系”。
weak 修饰符弱引用对象,不改变对象的引用计数,当其指向的对象被销毁时,它会自动的置为 nil。所以weak优于unsafe_unretained,不会发生野指针现象