博客> NSString copy和strong的区别,什么时候用copy,什么时候用strong?
NSString copy和strong的区别,什么时候用copy,什么时候用strong?
2018-11-11 20:35 评论:0 阅读:562 我耐你
NSString copy strong

我们定义一个类,并为其声明两个字符串属性,如下所示:

@interface ViewController ()

@property(nonatomic, strong) NSString *strongStr;

@property(nonatomic, copy) NSString *copyedStr;

@end 上面的代码声明了两个字符串属性,其中一个内存特性是strong,一个是copy。下面我们来看看它们的区别。

首先,我们用一个不可变字符串来为这两个属性赋值,

  • (void)test {

    NSString *testStr = [NSString stringWithFormat:@"123"];

    self.strongStr = testStr;

    self.copyedStr = testStr;

    NSLog(@"testStr=%p", testStr);

    NSLog(@"strongStr=%p", self.strongStr);

    NSLog(@"copyedStr=%p", self.copyedStr);

} 其输出结果是:

2018-02-26 13:03:22.080907+0800 tes[5408:409468] testStr=0xa000000003332313

2018-02-26 13:03:22.081044+0800 tes[5408:409468] strongStr=0xa000000003332313

2018-02-26 13:03:22.081139+0800 tes[5408:409468] copyedStr=0xa000000003332313

我们可以看到,这种情况下,不管是strong还是copy属性的对象,其指向的地址都是同一个,即为string指向的地址。

接下来,我们把testStr由不可变改为可变对象,看看会是什么结果。即将下面这一句

NSMutableString *testStr = [NSMutableString stringWithFormat:@"123"]; 其输出结果是:

2018-02-26 13:03:59.758429+0800 tes[5430:412707] testStr=0x604000242190

2018-02-26 13:03:59.758555+0800 tes[5430:412707] strongStr=0x604000242190

2018-02-26 13:03:59.758648+0800 tes[5430:412707] copyedStr=0xa000000003332313

可以发现,此时copy属性字符串已不再指向testStr字符串对象,而是深拷贝了testStr字符串,并让copyStr对象指向这个字符串。

此时,我们如果去修改testStr字符串的话,可以看到:因为strongStr与testStr是指向同一对象,所以strongStr的值也会跟随着改变;而copyStr是指向另一个对象的,所以不会改变。

结论

由于NSMutableString是NSString的子类,所以一个NSString指针可以指向NSMutableString对象.

而上面的例子可以看出,当原字符串是NSString时,由于字符串是不可变的,所以,不管是strong还是copy属性的对象,都是指向原对象,copy操作只是做了次浅拷贝。

当原字符串是NSMutableString时,strong属性只是增加了源字符串的引用计数,而copy属性则是对源字符串做了次深拷贝,产生一个新的对象,且copy属性对象指向这个新的对象。另外需要注意的是,这个copy属性对象的类型始终是NSString,而不是NSMutableString,因此其是不可变的。

这里还有一个性能问题,即在源字符串是NSMutableString,strong是单纯的增加对象的引用计数,而copy操作是执行了一深拷贝,所以性能上会有所差异。而如果原字符串是NSString时,则没有这个问题。

所以,我们一般采用copy修饰字符串,防止修改NSMutableString类型的字符串导致原来的数据被修改掉.

收藏
2
sina weixin mail 回到顶部