copy、mutableCopy、单层深拷贝

我记得刚开始开发的时候,有一段时间我一直以为浅拷贝==copy, mutableCopy==深拷贝, 由于没有仔细研究,闹过一段时间笑话。

深拷贝浅拷贝的概念直接抄录如下:

浅拷贝:指针拷贝,不产生新的对象,源对象的引用计数器+1;
深拷贝:对象拷贝,会产生新的对象,源对象的引用计数器不变;

Example 1

 NSArray * array = [NSArray arrayWithObjects:@"abc", @"lucy", nil];

NSMutableArray * array1 = [array copy];
  // 调用这个方法会crash
  //  [array1 addObject:@"Lili"];

NSMutableArray * array2 = [array mutableCopy];
[array2 addObject:@"Lili"];

NSLog(@"array: %@ -%p",[array class],array);
NSLog(@"array1: %@ -%p",[array1 class],array1);
NSLog(@"array2: %@ -%p",[array2 class],array2);

打印结果:


example-1.png

不可变类型array的copy操作是浅拷贝,生成一个不可变对象;mutableCopy是深拷贝,生成一个可变对象。

Example 2

 NSMutableArray * array = [NSMutableArray arrayWithObjects:@"abc", @"lucy", nil];

NSMutableArray * array1 = [array copy];
// 调用这个方法会crash
//  [array1 addObject:@"Lili"];

NSMutableArray * array2 = [array mutableCopy];
[array2 addObject:@"Lili"];

NSLog(@"array: %@ -%p",[array class],array);
NSLog(@"array1: %@ -%p",[array1 class],array1);
NSLog(@"array2: %@ -%p",[array2 class],array2);
/ ** 打印结果
 array: __NSArrayM -0x600002be7750
 array1: __NSArrayI -0x6000025afe80
 array2: __NSArrayM -0x600002be7a20
*/

可变类型array的copy操作是深拷贝,生成一个不可变对象;mutableCopy是深拷贝,生成一个可变对象。

原对象类型 拷贝方法 深/浅拷贝 副本对象类型
NSArray copy 浅拷贝 NSArray
NSArray mutableCopy 深拷贝 NSMutableArray
NSMutableArray copy 深拷贝 NSArray
NSMutableArray mutableCopy 深拷贝 NSMutableArray

Example 3 单层深拷贝和完全深拷贝

 NSMutableString * str1 =  [NSMutableString stringWithString:@"Bian"] ;
NSMutableString * str2 = [NSMutableString stringWithString:@"Sun"] ;
NSMutableArray * mutableArr = [[NSMutableArray alloc] initWithObjects:str1,str2, nil];
NSMutableArray * copyMutableArr = [mutableArr mutableCopy];

NSLog(@"mutableArr:%p %p %p",mutableArr,mutableArr[0],mutableArr[1]);
NSLog(@"copyMutableArr:%p %p %p",copyMutableArr,copyMutableArr[0],copyMutableArr[1]);
 // 修改str1的值
 [str1 insertString:@"abc" atIndex:0];
NSLog(@"mutableArr:%p %p %p",mutableArr,mutableArr[0],mutableArr[1]);
NSLog(@"copyMutableArr:%p %p %p",copyMutableArr,copyMutableArr[0],copyMutableArr[1]);
NSLog(@"%@",copyMutableArr[0]);
/** 打印结果:
mutableArr:0x600003ddaa90 0x600003ddaa30 0x600003dda9d0
copyMutableArr:0x600003ddaac0 0x600003ddaa30 0x600003dda9d0
mutableArr:0x600003ddaa90 0x600003ddaa30 0x600003dda9d0
copyMutableArr:0x600003ddaac0 0x600003ddaa30 0x600003dda9d0
copyMutableArr的str1的值:abcBian
*/

mutableArr的深拷贝copyMutableArr开辟了新的内存,但是里面值得内存地址还和mutableArr共享一份地址,明显就是指针拷贝,所以说这不是完全意义上的深拷贝,叫单层深拷贝!

那么如何实现完全深拷贝呢?
如下
//只需这样创建深拷贝,就是完全深拷贝
 NSMutableArray * copyMutableArr = [[NSMutableArray alloc] initWithArray:mutableArr copyItems:YES];

结论:

  • 可变对象的copy和mutableCopy方法都是深拷贝;
  • 不可变对象的copy方法是浅拷贝,mutableCopy方法是深拷贝;
  • copy方法返回的对象都是不可变对象。

你可能感兴趣的:(copy、mutableCopy、单层深拷贝)