直接上结论
[immutableObject copy] 不可变
[immutableObject mutableCopy] 可变
[mutableObject copy] //不可变
[mutableObject mutableCopy] //可变
[immutableArray copy] // 浅复制
[immutableArray mutableCopy] //单层深复制
[mutableArray copy] //单层深复制
[mutableArray mutableCopy] //单层深复制
对象类型不必说,复制之后都是新对象,指向不同的的地址。
解释一下这里声明的浅复制,单层深复制
浅复制 : 创建的新容器还是指向之前的地址,但是容器里面的元素还是指向相同的地址。
所有就copy与mutableCopy而言是无法完全实现拷贝一个全新的对象的。这个时候就轮到它出场了。
- (instancetype)initWithArray:(NSArray<ObjectType> *)array copyItems:(BOOL)flag;
官方文档是这样的定义的。
//If YES, each object in array receives a copyWithZone: message to create a copy of the object—objects must conform to the NSCopying protocol. In a managed memory environment, this is instead of the retain message the object would otherwise receive. The object copy is then added to the returned array.
//If NO, then in a managed memory environment each object in array simply receives a retain message when it is added to the returned array.
也就是当YES的时候,容器里的每个对象都会收到copyWithZone的消息转发。
所以这也要求,里面的元素都遵守并实现了NSCopying的协议方法,然后实现
- (id)copyWithZone:(NSZone *)zone
- (id)mutableCopyWithZone:(nullable NSZone *)zone
当然系统的容器类都实现了,所以当自己创建的对象时,记得要实现这一方法,一般MJModel或者YYModel都实现了这个协议的。
用了它之后,就会发现这个时候复制又会深入一层。同时容器类执行相应的copyWithZone方法,immutableArray与mutableArray的实际执行又不一样。但是最终都无法直接实现多层容器的深复制。
这个时候又有两个方法可以操作一番了。
1.暴力解归档,这个最直接也是最方便的了。
2.对容器的元素也逐级复制。应该是swizzle一下mutableCopy,然后针对集合里面的元素也深复制就好了。
附上Demo地址,自己跑一遍,结果一目了然。
iOS 集合的深复制与浅复制
iOS中的copy,mutableCopy,深拷贝和浅拷贝
copy和mutableCopy都是浅拷贝!!!
IOS开发之深拷贝与浅拷贝(mutableCopy与Copy)详解
复制对象(一)copy和mutableCopy方法
从@property (nonatomic, copy) NSString *name;这个细思极恐的代码规范说起