[iOS]深拷贝/浅拷贝区别
来点鸡汤:
// 所谓拷贝 就是在原有的对象的基础上产生一个新的副本对象.有两点原则:
// 1. 改变原对象的属性和行为不会影响副本对象
// 2. 改变副本对象的属性和行为不会影响原对象
来段示例代码
<pre>
-
(void)viewDidLoad {
[super viewDidLoad];
/##########################################/
// 以NSArray 为例
/##########################################/// 1. 不可变对象调用copy方法
NSArray *arr1 = [NSArray arrayWithObjects:@"1", nil];
// 不会产生新对象
NSArray *copyArr1 = [arr1 copy];NSLog(@"%p, %p\n", arr1, copyArr1);
1.不可变对象调用copy方法.png
NSLog(@"%ld, %ld\n", [arr1 retainCount], [copyArr1 retainCount]); // 字符串引用计数-1
/##########################################/
// 打印结果
0x7fbdd340dbf0, 0x7fbdd340dbf0
2, 2
// 这个为浅拷贝, 没有产生新对象, copyArr1还是指向arr1的地址
/##########################################/
// 2. 不可变对象调用mutableCopy方法
NSArray *arr2 = [NSArray arrayWithObjects:@"2", nil];
// 会产生新的可变对象
id mutableCopyArr2 = [arr2 mutableCopy];NSLog(@"%@, %p, %p\n", [mutableCopyArr2 class], arr2, mutableCopyArr2);
2.不可变对象调用mutableCopy方法.png
NSLog(@"%ld, %ld", [arr2 retainCount], [mutableCopyArr2 retainCount]);
/##########################################/
// 打印结果
__NSArrayM, 0x7fbdd3600250, 0x7fbdd36445ba
1, 1
// __NSArrayM类型是可变数组, 这个为深拷贝, 产生新的对象, 引用计数分别为1
/##########################################/
// 3. 可变对象调用copy方法
NSMutableArray *arr3 = [NSMutableArray arrayWithObjects:@"3", nil];
// 会产生不可变对象
id copyArr3 = [arr3 copy];NSLog(@"%@, %p, %p\n", [copyArr3 class], arr3, copyArr3);
3.可变对象调用copy方法.png
NSLog(@"%ld, %ld", [arr3 retainCount], [copyArr3 retainCount]);
/##########################################/
// 打印结果
__NSArrayI, 0x7fb120f12a40, 0x7fb120f10c70
1, 1
// NSArrayI代表不可变数组, 这个为深拷贝, 产生新对象(由可变对象变成不可变对象), 引用计数分别为1
/##########################################/
// 4. 可变对象调用mutableCopy方法
NSMutableArray *arr4 = [NSMutableArray arrayWithObjects:@"4", nil];// 会产生可变对象
id mutableCopyArr4 = [arr4 mutableCopy];NSLog(@"%@, %p, %p", [arr4 class], arr4, mutableCopyArr4);
4.可变对象调用mutableCopy方法.png
NSLog(@"%ld, %ld", [arr4 retainCount], [mutableCopyArr4 retainCount]);
/##################################################/
// 打印结果
__NSArrayM, 0x7fc06062f930, 0x7fc06052f960
1, 1
// NSArrayM代表可变数组, 这个为深拷贝, 地址不同, 引用计数分别为1
/##################################################/
// 总结:
/*
只有在第一种情况才是浅复制
运用copy的终极目的是: 当我赋值后,改变旧值不会影响新值. 如果要改变,就用retain
浅拷贝: 好比是你的影子, 你完了, 影子也完了.
深拷贝: 好比是你的克隆人, 你完了, 克隆人还在.*/
}
</pre>