您的位置:首页 > 移动开发 > IOS开发

[iOS]NSString到底使用Copy还是使用Strong属性,有什么区别

2017-03-18 11:24 696 查看
其实一直以来,没有真正搞懂,他们两个的区别,只是概念上知道,strong是强引用,copy是复制一份,引用计数加1。

使用上习惯

 Property (nonatomic,copy) NSString * s1;

为什么这样用,有时用strong程序也没出现问题,就真的不知道他们真正的区别在那,

直到看到Wei_vv的这篇blog,分析,理解,写的测试代码,才真正搞明白。对于iOS老司机来说汗颜了。
http://blog.csdn.net/weweco/article/details/47107277
以前在自学OC的时候和实际的项目中,都没有关注这一个小问题,一直使用Strong属性声明,也没发现项目中出现过由于NSString导致的未知Bug。某一天看到南峰子的blog,我也来测试以下看看具体区别。

1.首先分别定义这个两个属性 NSString。

@property (nonatomic,strong)NSString  *strongStr;

@property (nonatomic,copy 
)NSString  *copyssStr;

2.然后声明一个不可变的NSSring对象,给这两个属性对象赋值,分别输出他们的指针和内存地址。

- (void)test{

    NSString *string = [NSStringstringWithFormat:@"测试文字"];//注释1

    self.strongStr = string;

    self.copyssStr = string;

    

    NSLog(@"测试文字   String: %p, %p", string, &string);

    NSLog(@"Strong属性 String: %p, %p",_strongStr, &_strongStr);

    NSLog(@"Copy  属性 String: %p, %p",_copyssStr, &_copyssStr);

}

输出如下:

测试文字   String: 0x7fade9740800, 0x7fff507f06d8

Strong属性 String: 0x7fade9740800, 0x7fade94adf70

Copy  属性 String: 0x7fade9740800, 0x7fade94adf78

结果表明:不管是Strong还是Copy属性的对象,指向的地址都是同一个原来String指向的地址。

如在MRC环境,输出String的引用计数,会看到其引用计数值是3,即Strong操作和Copy操作都会使原字符串对象的引用计数值加了1。

3.接着再声明一个可变的NSSring对象,给这两个属性对象赋值,分别输出他们的指针和内存地址。

只替换注释1 代码为以下代码,输出。

NSMutableString *string = [NSMutableStringstringWithFormat:@"测试文字"];

输出如下:

测试文字   String: 0x7f892bf29760, 0x7fff592ca6d8

Strong属性 String: 0x7f892bf29760, 0x7f892bc42480

Copy  属性 String: 0x7f892be7d2f0, 0x7f892bc42488

结果输出有不同:此时Copy属性字符串已不再指向原来String对象,而是深拷贝了String字符串,且copyssString对象指向这个字符串。
在MRC环境下,输出两者的引用计数,可以看到String对象的引用计数是2,而copyssString对象的引用计数是1。
如果去修改String字符串的话,可以看到:因为strongString与原始String是指向同一对象,所以strongString的值也会跟随着改变(此时strongString的类型实际上是NSMutableString,而不是NSString);而copyssString是指向另一个对象,并不会改变。

4.最后结论
我们知道NSMutableString是NSString的子类,一个NSString指针可以指向NSMutableString对象,strongString指针指向一个可变字符串是正常的。

如上例子可以看出:
1) 当原字符串是NSString时,字符串是不可变的,不管是Strong还是Copy属性的对象,都是指向原对象,Copy操作只是做了次浅拷贝。

2) 当原字符串是NSMutableString时,Strong属性只是增加了原字符串的引用计数,而Copy属性则是对原字符串做了次深拷贝,产生一个新的对象,且Copy属性对象指向这个新的对象,且这个Copy属性对象的类型始终是NSString,而不是NSMutableString,因此其是不可变的。
3) 这里还有一个性能问题,即在原字符串是NSMutableString,Strong是单纯的增加对象的引用计数,而Copy操作是执行了一次深拷贝,所以性能上会有所差异(虽然不大)。如果原字符串是NSString时,则没有这个问题。
所以,在声明NSString属性时,到底是选择strong还是copy,可以根据实际情况来定。不过,一般我们将对象声明为NSString时,都不希望它改变,所以大多数情况下,我们建议用copy,以免因可变字符串的修改导致的一些非预期问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  IOS copy Strong 区别
相关文章推荐