深拷贝和浅拷贝的区别

一.深拷贝

源对象和副本对象是不同的两个对象

源对象引用计数不变,副本对象计数器为1(因为是新产生的)


至少有一层是对象复制


二.浅拷贝

源对象和副本对象是同一个对象

源对象(副本对象)引用计数器+1,相当于做一次retain操作

本质:没有产生新的对象


三.完全复制

对于被复制的对象每一层都是对象复制


四.哪些是深拷贝,哪些是浅拷贝

retain:始终是浅复制;返回对象是否可变与被复制的对象保持一致

copy:对于可变对象是深拷贝,返回一个不可变对象

           对于不可变对象为浅拷贝,返回一个不可变对象

mutableCopy:始终是深拷贝,始终返回一个可变对象


五:例子

1.NSString中为什么用copy

1)声明2个字符串属性,一个为strong,一个为copy

@interface TestString : NSObject

@property (nonatomic, strong) NSString *strongString;
@property (nonatomic, copy) NSString *copyedString;

@end

2)用一个不可变字符串来为这两个属性赋值

-(void)test{

    NSString *str = @"淩凌0";
    self.strongString = str;
    self.copyedString = str;
    NSLog(@"str:%p",str);
    NSLog(@"strongString:%p",self.strongString);
    NSLog(@"copyedString:%p",self.copyedString);
}


3)输出结果

2015-12-21 14:56:09.335 使用copy[927:68174] strM:0x100004260
2015-12-21 14:56:09.336 使用copy[927:68174] strongString:0x100004260
2015-12-21 14:56:09.336 使用copy[927:68174] copyedString:0x100004260

结论:不管是strong还是copy属性的对象,其指向的地址都是同一个,为string指向的地址。如果我们换作MRC环境,打印string的引用计数的话,会看到其引用计数值是3,即strong操作和copy操作都使原字符串对象的引用计数值加了1。


4)将NSString改为NSMutableString

-(void)test{

//    NSString *str = @"淩凌0";
    NSMutableString *strM = [NSMutableString stringWithString:@"淩凌0"];
    self.strongString = strM;
    self.copyedString = strM;
    NSLog(@"strM:%p",strM);
    NSLog(@"strongString:%p",self.strongString);
    NSLog(@"copyedString:%p",self.copyedString);
}

5)打印结果

2015-12-21 14:49:10.860 使用copy[907:65503] strM:0x100206ed0
2015-12-21 14:49:10.861 使用copy[907:65503] strongString:0x100206ed0
2015-12-21 14:49:10.861 使用copy[907:65503] copyedString:0x100207020

结论:此时copy属性字符串已不再指向string字符串对象,而是深拷贝了string字符串,并让_copyedString对象指向这个字符串。在MRC环境下,打印两者的引用计数,可以看到string对象的引用计数是2,而_copyedString对象的引用计数是1。


最后:

一般我们将对象声明为NSString类型时,都不希望它改变,所以大多数情况下,使用copy,以免因可变字符串的修改导致一些非预期问题

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值