copy和strong的区别

本文通过实例详细解析了Objective-C中copy与strong属性的区别,重点介绍了它们如何影响字符串对象(NSMutableString与NSString)。通过对比深拷贝与浅拷贝的行为,帮助理解不同属性对对象引用及复制的影响。

对于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,那两都没啥区别。不会影响安全性,内存管理也一样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值