OC中属性修饰符有很多,比如说raadwrite,readonly,weak,copy,assign,retain,nonatomic,atomic等,然而这些修饰符有什么区别呢,下面就简要的说一下。
readwrite故名思意,可读可写,这我们可以理解为用readwrite修饰的属性需要生成getter方法和setter方法。
readonly只读,即只会生成getter方法,不会生成setter方法,我们在定义这种类的时候我们是不希望外界直接对该类的这一属性做直接修改的,当然可以通过接口或者属性包含的下层来实现重新赋值,比如说控件的frame。
assign:赋值属性,setter方法将传入参数赋值给实例变量,所以这一属性仅仅在设置变量的时候使用。
retain:持有属性,当调用setter方法时会将传入的参数先保留,然后在赋值,相应的传入参数的retaincount会+1。
copy:赋值特性,setter方法将传入的对象在内存中复制一份。所以copy常用于要生成一个新的变量并操作是使用。
nonatomic:非原子性操作,决定让编译器生成的getter setter是否是原子操作,atomic表示多线程安全,开发中产过的是nonatomic.
然而copy和strong有什么区别呢;
家下来举个例子,
#import "testObject.h"
@interface testObject()
@property(nonatomic,copy)NSString * str1;
@property(nonatomic,strong)NSString * str2;
@end
@implementation testObject
-(void)test{
NSString * string = [NSString stringWithFormat:@"test"];
self.str1 = string;
self.str2 = string;
NSLog(@"oringin string: %p %p",string,&string);
NSLog(@"strong string %p %p",self.str1,&_str1);
NSLog(@"copy string %p %p",self.str2,&_str2);
}
@end当调用test方法时,输出结果如何:
2017-07-02 20:42:20.981406+0800 testProperty_[1347:445563] oringin string: 0x7473657445 0x7fff5fbff628
2017-07-02 20:42:20.981453+0800 testProperty_[1347:445563] strong string 0x7473657445 0x7fff5fbff628
2017-07-02 20:42:20.981467+0800 testProperty_[1347:445563] copy string 0x7473657445 0x7fff5fbff628
可以看出strong和copy地址相同,即str1和str2指向同一段内存,但是我们如果把string类型改成NSMutableString,可以看到打印内容为:
2017-07-03 19:18:41.859963+0800 testProperty_[2679:912096] oringin string: 0x100303c90 0x7fff5fbff628
2017-07-03 19:18:41.860006+0800 testProperty_[2679:912096] strong string 0x7473657445 0x100400368
2017-07-03 19:18:41.860027+0800 testProperty_[2679:912096] copy string 0x100303c90 0x100400370
此时str1和str2指向不同的存储,我们可以得出结论:当我们使用strong修饰的时候,生成的是一个指针指向原内存,则此时str2的引用计数+1,而使用copy的时候,生成了一段新的内存空间,此时str1的引用计数不增加,所以使用copy的时候性能并没有strong要好,这个也是深拷贝和浅拷贝的区别。
所以,在声明NSString属性时,到底是选择strong还是copy,可以根据实际情况来定。不过,一般我们将对象声明为NSString时,都不希望它改变,所以大多数情况下,我们建议用copy,以免因可变字符串的修改导致的一些非预期问题。