在ios开发中,经常涉及到深拷贝和浅拷贝的问题,针对深拷贝和浅拷贝,为了方便大家的理解,专门总结了以下3种方式(其实本质是一样的)。
一. 理解一
浅拷贝是拷贝操作后,并没有进行真正的复制,而是另一个指针也指向了同一个地址。深拷贝,拷贝操作后,是真正的复制了一份,另一个指针指向了,拷贝后的地址。如下图:A代表原有的指针,B代表拷贝的指针。(图一为浅拷贝,图二为深拷贝)。
--浅拷贝------------------>深拷贝--
从上图中可以看到,浅拷贝(浅复制)中如果其中A指针改变了所指向的地址的内容,那么B指针也指向被修改后的内容。如果有些地方用到B指针,即便A指向的内容发生变化,也不希望B受到影响,则需要用深拷贝,真正复制一份A指向的内容,B指向复制后的值,这样即使A指向的内容变化了,B也不会产生影响。网上也有人通俗理解为:浅复制好比你和你的影子,你完蛋,你的影子也完蛋。深复制好比你和你的克隆人,你完蛋,你的克隆人还活着。
二. 理解二
深拷贝和浅拷贝的本质是地址相同,就是浅拷贝,地址不同就是深拷贝。
ios开发过程中,大体上会区分为对象和容器两个概念,对象的copy是浅拷贝,mutablecopy是深拷贝。容器也参照如上方法,但是需要记住,容器的包含对象的拷贝,无论使用copy,还是mutablecopy都将是浅拷贝。要想实现对象的深拷贝,必须自己提供拷贝的方法。自己提供的方法见下面的注意点。
三. 理解三(代码方式)
NSArray *array=[NSArray arrayWithObjects:@"one",@"two", nil];
NSMutableArray *array1=[array copy];
[array1 addObject:@"three"];
//这段代码是错误的。array1,通过copy进行的是浅拷贝,即并没有真正复制array,而是也指向了array,此时array是不可变数组,无法进行新数据的添加
NSArray *array=[NSArray arrayWithObjects:@"one",@"two", nil];
NSMutableArray *array2=[array mutableCopy];
[array2 addObject:@"three"];
//这段代码是正确的,array2通过mutableCopy进行的是深拷贝,即把array真正复制了一份,并且复制后,变为了NSMutableArray ,此时array2是可变数组,可以添加数据。
注意点:(1)当使用mutableCopy时,不管源对象是否可变,副本是可变的,并且实现真正意义上的拷贝。
当我们使用copy一个可变对象时,副本对象是不可变的。
(2)要想实现对象的自定义拷贝,必须实现NSCopying,NSMutableCopying协议,实现该协议的copyWithZone方法和mutableCopyWithZone方法。深拷贝和浅拷贝的区别就在于copyWithZone方法的实现。