iOS 深拷贝与浅拷贝---copy/mutableCopy

一、拷贝的目的

  • 产生一个副本对象;
  • 修改了源对象,不会影响副本对象;
  • 修改了副本对象,不会影响源对象;
    在理解上,可类比Word文档的拷贝

二、如何实现拷贝

ios中用copy和mutableCopy来实现

NSString *str1 = @"123";
NSString *str2 = [str1 copy];
NSMutableString *str3 = [str1 mutableCopy];
NSLog(@"%@,%@,%@",str1,str2,str3);
iOS 深拷贝与浅拷贝---copy/mutableCopy_第1张图片
打印结果

三、copy和mutableCopy的不同点

  • 二者的区别:
    copy产生不可变副本;
    mutableCopy产生可变副本;
1.验证copy的不可变性
NSString *str1 = @"123";
NSMutableString *str2 = [str1 copy];//此处为验证是否为不可变对象
NSMutableString *str3 = [str1 mutableCopy];
[str2 appendString:@"45"];
[str3 appendString:@"45"];
iOS 深拷贝与浅拷贝---copy/mutableCopy_第2张图片
str2追加字符串崩溃
2.验证mutableCopy的可变性
NSString *str1 = @"123";
NSString *str2 = [str1 copy];
NSMutableString *str3 = [str1 mutableCopy];
[str3 appendString:@"45"];
NSLog(@"%@,%@,%@",str1,str2,str3);
iOS 深拷贝与浅拷贝---copy/mutableCopy_第3张图片
str3追加字符串正常显示
3.从内存地址的角度看
(1)源对象为不可变对象的情况
NSString *str1 = @"123";
NSString *str2 = [str1 copy];
NSMutableString *str3 = [str1 mutableCopy];
NSLog(@"%p,%p,%p",str1,str2,str3);
内存地址的打印结果

iOS 深拷贝与浅拷贝---copy/mutableCopy_第4张图片
内存分布示意图

从内存分布上来看,copy没有产生新的对象,而mutableCopy产生了新的对象并且指针指向了新的内存区域。

在这里不禁怀疑:不是说copy或者mutableCopy都产生新的副本,两者之间互不影响么?

解疑:首先,在这里源对象是不可变的,copy产生的是不可变对象,那么既然新产生的对象也是不可变的,从内存优化的角度来说,也就没有必要产生新的内存区域,直接生成一个新的指针指向原来的不可变对象就OK了;而mutableCopy操作之后得到的是可变对象,那么必然要新生成一个内存空间去存放可变的副本。

(2)源对象为可变对象的情况
NSMutableString *str1 = [NSMutableString stringWithString:@"123"];
NSString *str2 = [str1 copy];
NSMutableString *str3 = [str1 mutableCopy];
NSLog(@"%p,%p,%p",str1,str2,str3);
iOS 深拷贝与浅拷贝---copy/mutableCopy_第5张图片
内存地址打印结果

iOS 深拷贝与浅拷贝---copy/mutableCopy_第6张图片
内存分布示意图

同理,源对象为可变对象,copy之后为不可变对象,所以内存地址不同;mutableCopy之虽然为可变对象,但是为了达到,副本和源对象互不影响的目的,同样产生了新的内存空间。

四、总结

  • 深拷贝:内容拷贝,有产生新对象
  • 浅拷贝:指针拷贝,没有产生新对象
NSString *str1 = @"123";
NSString *str2 = [str1 copy];               //浅拷贝
NSMutableString *str3 = [str1 mutableCopy]; //深拷贝
NSLog(@"%p,%p,%p",str1,str2,str3);
0x100001040,0x100001040,0x10062c8c0
NSMutableString *str1 = [NSMutableString stringWithString:@"123"];
NSString *str2 = [str1 copy];               //深拷贝
NSMutableString *str3 = [str1 mutableCopy]; //深拷贝
NSLog(@"%p,%p,%p",str1,str2,str3);
0x10067d480,0xb0dbfc7d66059a9b,0x10067d540
  • 所以,不一定copy就是浅拷贝,mutableCopy就是深拷贝,具体情况具体分析。

同样类比NSString,分析出NSdictionary和NSArray也是同样的道理。以下给出表格。


iOS 深拷贝与浅拷贝---copy/mutableCopy_第7张图片
常用系统类的拷贝情况

一句话:不可变对象的copy是浅拷贝,剩下的都是深拷贝

你可能感兴趣的:(iOS 深拷贝与浅拷贝---copy/mutableCopy)