@property的常用属性关键字有nonatomic、atomic、readonly、writeonly、readwrite、assign,copy、strong、weak、看着挺多的,但是经常用的也就几个
notomic: 默认关键字,也就是说如果什么都不写,默认就是这个。表示该属性是线程同步的。一般用不到,会影响性能。
nonatomic: 非线程同步,基本都是用这个。保证属性不会被其他线程修改
readwrite: 默认关键字,表示可读可写(基本上不用特别声明这个属性是默认的)。
readonly: 只能读(get),不能写(set),当你希望属性不能被外界直接修改,但是可以访问时使用。
writeonly: 只能写(set),不能读(get)。
assign: 默认关键字。非对象类型一般使用此关键字。(没有索引,只能赋值使用,如果用于对象,会出现野指针问题) retain: 对象的引用计数+1。ARC下已经不再使用此关键字,用strong代替。 copy: 拷贝一个新的对象,新对象的引用计数+1,原对象不变。 strong: 能够维持对象的生命。
weak、assign的使用场景和异同
不希望持有对象时使用weak关键字,比如代理,UI控件(看过很多代码里
面UI控件都是使用的strong,其实没有必要,因为父视图会持有子视图,
会维持子视图的生命,父视图一旦死了,子视图也就跟着死了),避免循
环引用的__weak等。 weak, assign都不会影响对象的引用计数。当一个
对象的引用计数为0时,所有指向该对象的weak属性指针会被自动设置为
nil,而assign属性不会,如果对象被释放了,此时再进行访问,程序崩溃。(指针地址还在对象没有了。)
strong的使用(非ARC就是retain)
OC对象类型(NSArray、NSDate、NSNumber、模型类)(省事的时候可以用strong对于任何对象)
一个对象只要有强指针引用着,就不会被销毁
copy的使用
NSString、NSArray、NSDictionary 等等经常使用copy关键字,是因为他
们有对应的可变类型:NSMutableString、NSMutableArray、
NSMutableDictionary;他们之间可能进行赋值操作,为确保对象中的字符串
值不会无意间变动,应该在设置新属性值时拷贝一份。
如:@property (copy) NSMutableArray *array;
两个问题:1、添加,删除,修改数组内的元素的时候,程序会因为找不到对应的方
法而崩溃.因为copy就是复制一个不可变NSArray的对象;2、使用了atomic属
性会严重影响性能 ;
用@property声明的NSString(或NSArray,NSDictionary)经常使用copy关键字,为什么?如果改用strong关键字,可能造成什么问题?
- 使用copy无论给我传入是一个可变对象还是不可对象,我本身持有的就
是一个不可变的副本. - 如果我们使用是strong,(引用类型),那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性.
- 不要将copy关键字属性用到NSMutableString,NSMutableArray,NSMutableDictionary等可变对象上,除非有特别的需求。如果属性是 copy 的,那么系统默认只会在 set 方法中调用 copy 的方法:具体原因参考文章
非集合与集合的copy与Mutablecopy方法解析(不需要纠结)
在非集合类对象中:
- 对immutable对象进行copy操作,是指针复制,mutableCopy操作时内容复制;
- 对mutable对象进行copy和mutableCopy都是内容复制
伪代码
[immutableObject copy] // 浅复制
[immutableObject mutableCopy] //深复制
[mutableObject copy] //深复制
[mutableObject mutableCopy] //深复制
对于集合对象
- 对于不可变的集合对象,copy 是浅拷贝,mutableCopy 是单层深拷贝。
- 对于可变的集合对象,无论 copy 或者 mutableCopy 都是单层深拷贝。
让自己的类用 copy 修饰符,重写带 copy 关键字的 setter
若想令自己所写的对象具有拷贝功能,则需实现NSCopying协议。如果
自定义的对象分为可变版本与不可变版本,那么就要同时实现
NSCopying与NSMutableCopying协议。
unsafe_unretained、nonnull、nullable、null_resettable,