深拷贝和浅拷贝是一个经常问到的问题。
很多人认为copy是浅拷贝,mutableCopy是深拷贝。在解释copy与mutableCopy的区别,我们先搞清楚什么是深拷贝和浅拷贝
从图我们看出来浅拷贝只是拷贝了指针,而并未拷贝对象本身。而深拷贝则是指针和对象本身都进行了拷贝
代码演示
使用不可变集合对象
NSArray *array = @[@"4444"];
NSArray *array2 = array;
NSLog(@"array === %p %p", &array, array);
NSLog(@"array2 === %p %p", &array2, array2);
打印结果
array === 0x7fff5fbff738 0x100403120
array2 === 0x7fff5fbff730 0x100403120
array与array2指针地址不同
mutableCopy
NSArray *array = @[@"4444"];
NSArray *array2 = [array mutableCopy];
NSLog(@"array === %p %p", &array, array);
NSLog(@"array2 === %p %p", &array2, array2);
打印结果
array === 0x7fff5fbff738 0x100203520
array2 === 0x7fff5fbff730 0x1002024e0
我们发现两者的指针指着不一样,内容也不一样,也就是说,实现了内容和指针的拷贝。也就是深拷贝
那是用copy时候的打印结果是什么?
打印结果
array === 0x7fff5fbff738 0x100202b90
array2 === 0x7fff5fbff730 0x100202b90
结果是内容没有拷贝,而指针进行了拷贝。故copy为浅拷贝
结论
使用不可变对象时,无论是copy还是mutableCopy。结果都是浅拷贝
使用可变对象
NSMutableArray *mutableArray = [NSMutableArray arrayWithObjects:@"111", @"222", nil];
NSMutableArray *array1 = [mutableArray copy];
NSLog(@"mutable ===== %p %p", &mutableArray, mutableArray);
NSLog(@"array1 ===== %p %p", &array1, array1);
打印结果
mutable ===== 0x7fff5fbff758 0x100203cb0
array1 ===== 0x7fff5fbff750 0x100203170
指针进行了拷贝,内容也进行了拷贝。所以是深拷贝。
NSMutableArray *mutableArray = [NSMutableArray arrayWithObjects:@"1111",@"22222", nil];
NSMutableArray *array = [mutableArray mutableCopy];
NSLog(@"mutable ===== %p %p", &mutableArray, mutableArray);
NSLog(@"array1 ===== %p %p", &array, array);
打印结果
mutable ===== 0x7fff5fbff758 0x100401270
array1 ===== 0x7fff5fbff750 0x100403230
其指针和内容都已经进行了改变。所以这个时候mutableCopy便是深拷贝了。
结论
对于使用可变对象时,copy和mutableCopy都是深拷贝。
那深拷贝和浅拷贝在使用上的区别呢?
NSArray *mutableArray = @[@"111"];
NSMutableArray *array = [mutableArray copy];
[array addObject:@"333"];
NSLog(@"%@", array);
打印结果
-[__NSSingleObjectArrayI addObject:]
说明array是不可变数组,那如何改变array呢?
NSArray *mutableArray = @[@"111"];
NSMutableArray *array = [mutableArray mutableCopy];
[array addObject:@"333"];
NSLog(@"%@", array);
我们发现此时array是可以更改的对象
最终结论
对于不可变对象而言,copy便是浅拷贝,而mutableCopy是深拷贝。
对于可变对象而言,copy和mutableCopy都是深拷贝。但是copy出来的对象是不可变的,而mutableCopy则是可变对象。