先来提到几个名词,然后我们通过实验,再总结结论.
浅拷贝 :不拷贝对象本身,仅仅是拷贝指向对象的指针. (不开辟新内存)
深拷贝 :直接拷贝整个对象内存到另一块内存中. (开辟新内存)
单层深拷贝 :深拷贝,但是里面的元素内存不会拷贝. (开辟新内存,但容器里的元素不开辟新内存)
双层深拷贝 :深拷贝,里面的元素内存也会拷贝. (开辟新内存,并且容器里的元素也开辟新内存)
非容器对象

可以看出,对于不可变NSString,
copy是浅拷贝,返回不可变对象,
mutableCopy 是深拷贝,返回可变对象.
既然copy后的对象和原对象指向的是同一块内存,那改变其中一个的值会不会影响另一个呢?

可以看出,当对str1重新赋值的时候,系统为它重新开辟了一块新的内存,
所以之前的copy和mutableCopy的对象值并不会改变. 对copyStr1重新赋值也是一样的道理.
容器对象

可以看出:
对于不可变NSArray,
copy是浅拷贝,返回不可变对象,
mutableCopy 是单层深拷贝,返回可变对象.
对于可变NSMutableArray,
copy是单层深拷贝,返回不可变对象,
mutableCopy是单层深拷贝,返回可变对象.
要注意,单层深拷贝,虽然开辟了新内存,但是里面元素的地址还是之前的地址,所以这时候如果对原对象内的元素进行修改,则会影响到copy和mutableCopy后的对象内容.
说了这么多,可能你脑瓜子嗡嗡的. 那你只需要记住一句话:
只有不可变对象创建不可变副本才是浅拷贝,其他都是深拷贝。
对于容器类的对象,分为单层深拷贝和双层深拷贝.
通常来说,容器里存放基本类型对象如:NSString 或者自定义对象如:User.
copy和mutableCopy都是单层深拷贝. 如果你修改了原对象里面的元素,那会影响copy和mutableCopy的对象的.
如果想要做到双层深拷贝. 容器里的元素需要遵守<NSCopying,NSMutableCopying>协议,还要实现他们的对应方法,这里就不详细介绍了.
你只要记得:
copy返回不可变,mutableCopy返回可变
对不可变的copy是浅拷贝,其它都是深拷贝.容器是单层深拷贝.
如有错误,还请指正!
网友评论