我们在声明一个NSString属性时,对于其内存相关特性,通常有两种选择(基于ARC环境):strong与copy。那这两者有什么区别呢?什么时候该用strong,什么时候该用copy呢?
首先举个例子:
这里有一个person类,有一个使用cooy的NSString属性.
毋庸置疑的是,字符串属性使用copy,当外界修改了字符串,里面不会改变.
在ViewController.m文件中
注意: 此时的NSString属性name是使用copy的.
- (void)viewDidLoad {
[super viewDidLoad];
// 不可变字符串
NSString *nameStr = @"zy";
Person *person = [[Person alloc] init];
person.name = nameStr;
NSLog(@"%p ---- %p",nameStr,person.name);
}
输出结果:
2017-08-31 18:17:20.992 NSSting_copy_strong[4661:196852] 0x10bbea070 ---- 0x10bbea070
因为NSString是不可变字符串,当使用copy的时候,不会生成一个新的对象,因为源对象是不可更改的对象,那么拷贝出来的也是不可更改的对象,两者互不影响.所以不会产生新的对象.
当把NSString的属性改为strong,此时仍使用NSString不可变字符串.打印结果如下:
2017-08-31 18:23:36.487 NSSting_copy_strong[4747:199526] 0x103e44068 ---- 0x103e44068
所以,在不可变字符串的情况下,无论使用strong,还是copy.其地址指向的都是同一块存储空间.
注意: 当把.m文件中的NSString不可变字符串改为可变字符串之后.
此时NSString的属性使用的strong.
- (void)viewDidLoad {
[super viewDidLoad];
// 可变字符串
NSMutableString *nameStr = [NSMutableString stringWithFormat:@"zy"];
Person *person = [[Person alloc] init];
person.name = nameStr;
NSLog(@"%p ---- %p",nameStr,person.name);
}
输出结果:
2017-08-31 18:27:05.561 NSSting_copy_strong[4845:202200] 0x6000000747c0 ---- 0x6000000747c0
而把NSString的属性改为copy后.
输出结果:
2017-08-31 18:29:07.405 NSSting_copy_strong[4900:203652] 0x600000268a40 ---- 0xa0000000000797a2
此时copy属性的字符串已经不再指向nameStr的内存地址了.而是深拷贝了一份内存地址,并让 _name属性指向这块内存地址.
当源字符串是NSString的时候,无论使用strong,copy属性的对象,都会指向源对象,此时copy只是做了一次浅拷贝.
当源字符串是NSSMutableString的时候,copy属性对源字符串做了一次深拷贝,创建了一个新的对象,并指向新对象的内存地址.
注意:
一般情况下我们在开发中使用的大多数都是NSString不可变字符串.在网络中加载的数据大多也是不可变的.当使用不可变字符的时候,strong,copy都不会产生新的对象.这个时候建议使用strong;原因如下:
当NSString属性使用copy的时候.
@property (nonatomic, copy) NSString *name;
此时name的set方法是这样的.
// copy情况下的属性name的set方法
- (void)setName:(NSString *)name
{
_name = [name copy];
}
在set方法中,每次都会去判断name是NSString的还是NSMutableString的.如果是NSString不可变字符串的时候,就不会去生成新的对象,如果是可变字符串,就会去生成新的对象.这样会进行一次判断操作.
当NSString属性使用strong的时候
@property (nonatomic, strong) NSString *name;
此时name的set方法是这样的
// strong情况下的属性name的set方法
- (void)setName:(NSString *)name
{
_name = name;
}
在set方法中不用去判断,外界传入的可变或不可变字符.这样提高了性能.所以当外界传入的字符串是NSString不可变字符串的时候,建议使用strong.
关于本章内容比较好的博文: http://www.cocoachina.com/ios/20150512/11805.html