copy和strong的区别

iOS 专栏收录该内容
43 篇文章 0 订阅

对于copy和strong的区别主要就是能区分深拷贝还是浅拷贝。
以字符串为例:

@property (retain,nonatomic) NSString *secondString;
@property (copy, nonatomic)   NSString *thirdString;

- (void)test
{
    NSMutableString *firstString = [NSMutableString stringWithFormat:@"hello"];
    self.secondString   = firstString;
    self.thirdString    = firstString;
    NSLog(@"firstString:%p,%p",  firstString,&firstString);
    NSLog(@"secondString:%p,%p", _secondString, &_secondString);
    NSLog(@"thirdString:%p,%p",   _thirdString, &_thirdString);
}

结果输出
2016-08-23 17:16:36.806 Test[2842:464972] firstString:0x7fec7580b7d0,0x7fff5b66ca48
2016-08-23 17:16:36.806 Test[2842:464972] secondString:0x7fec7580b7d0,0x7fec734d8810
2016-08-23 17:16:36.806 Test[2842:464972] thirdString:0xa00006f6c6c65685,0x7fec734d8818

可以从结果看出
firstString对象的地址为0x7fec7580b7d0,也就是0x7fec7580b7d0是@“hello”的首地址,mStr变量自身在内存中的地址为0x7fff5b66ca48;
当把firstString赋值给retain的secondString时,secondString对象的地址为0x7fec7580b7d0,rStr变量自身在内存中的地址为0x7fec734d8810;firstString与secondString指向同样的地址,他们指向的是同一个对象@“hello”,这个对象的地址为0x7fec7580b7d0,所以他们的值是一样的。
当把firstString赋值给copy的thirdString时,thirdString对象的地址为0xa00006f6c6c65685,thirdString变量自身在内存中的地址0x7fec734d8818;thirdString与firstString指向的地址是不一样的,他们指向的是不同的对象,所以copy是深复制,一个新的对象,这个对象的地址为0xa00006f6c6c65685,值为@“hello”。

增加如下代码:

   [firstString appendString:@"ddd"];
    NSLog(@"secondString:%@",_secondString);
     NSLog(@"thirdString:%@",_thirdString);


输出
2016-08-23 17:29:17.748 ECIphoneTest[3021:472901] secondString:helloddd
2016-08-23 17:29:17.748 ECIphoneTest[3021:472901] thirdString:hello

可见浅复制跟随改变,但是深复制没有改变。

对于将nesting赋值给copy和retain同理。

得出结论:
对源头是NSMutableString的字符串,retain仅仅是指针引用,增加了引用计数器,这样源头改变的时候,用这种retain方式声明的变量(无论被赋值的变量是可变的还是不可变的),它也会跟着改变;而copy声明的变量,它不会跟着源头改变,它实际上是深拷贝。

对源头是NSString的字符串,无论是retain声明的变量还是copy声明的变量,当第二次源头的字符串重新指向其它的地方的时候,它还是指向原来的最初的那个位置,也就是说其实二者都是指针引用,也就是浅拷贝。

另外说明一下,这两者对内存计数的影响都是一样的,都会增加内存引用计数,都需要在最后的时候做处理。

简单来说比如声明的一个NSString *secondString变量,然后把一个NSMutableString *firstString变量的赋值给它了,如果要求secondString跟着firstString变化,那么就用retain;如果secondString不能跟着firstString一起变化,那就用copy。而对于要把NSString类型的字符串赋值给secondString,那两都没啥区别。不会影响安全性,内存管理也一样。

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值