我记得刚开始开发的时候,有一段时间我一直以为浅拷贝==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);
打印结果:
不可变类型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方法返回的对象都是不可变对象。