简述用@property声明的 NSString / NSArray / NSDictionary 经常使用 copy 关键字,为什么?如果改用strong关键字,可能造成什么问题 ?
参考答案:
在Objective-C中,使用@property
声明属性时,copy
和strong
是两种不同的属性特性,它们决定了属性值的内存管理策略。对于NSString
、NSArray
和NSDictionary
这样的不可变对象(immutable objects),通常推荐使用copy
,而不是strong
。以下是原因:
为什么经常使用copy
关键字:
- 防止可变对象导致的副作用:如果你有一个
NSMutableString
、NSMutableArray
或NSMutableDictionary
,并且你将其赋值给一个使用strong
属性的NSString
、NSArray
或NSDictionary
属性,那么原始的可变对象的变化将会影响到这个属性。使用copy
可以确保你得到的是一个不可变的副本,从而避免这种副作用。 - 线程安全:在多线程环境中,使用
copy
可以确保每个线程都有自己的对象副本,从而避免线程间的数据竞争。 - 遵循不可变语义:对于声明为
NSString
、NSArray
或NSDictionary
的属性,我们通常期望它们是不可变的。使用copy
可以确保这一点,即使传入的是可变对象。
如果改用strong
关键字,可能造成什么问题:
- 意外修改:如前所述,如果属性是
strong
的,并且你传入了一个可变对象,那么对该可变对象的任何修改都会影响到属性。这可能会导致意外的副作用和难以追踪的bug。 - 线程安全问题:在多线程环境中,如果多个线程访问和修改同一个可变对象,而没有适当的同步机制,就会导致数据竞争和不一致的行为。
- 不符合预期的行为:开发者可能期望属性是不可变的,但如果使用
strong
,那么属性的行为就会与这种期望不符。
总的来说,对于不可变对象类型,使用copy
可以提供更强的数据保护和更清晰的语义。当然,如果你确定属性只会被赋值为不可变对象,并且不需要担心线程安全问题,那么使用strong
也是可以的。但在大多数情况下,为了安全起见,推荐使用copy
。