一、名词解释
1、 浅拷贝(shallow copy):只是增加了一个对被引用对象的一个指向,即指针拷贝,只是retainCount加一,实际上还是共用一块内存
2、深拷贝(one-level-deep copy):会分配出一块内存,然后将引用的内容拷贝进去,也就是说拷贝出来的对象与原对象是独立的。
【注意】如果mutableCopy的是集合对象,深拷贝的是该集合对象,不是指该集合对象里面的元素,称之为单层深拷贝,对该集合里的元素依然是指针拷贝
3、完全复制(real-deep copy)::在完全复制操作时,对于被复制对象的每一层都是对象复制。
顾名思义,浅复制,并不拷贝对象本身,仅仅是拷贝指向对象的指针;深复制是直接拷贝整个对象内存到另一块内存中。
一图以蔽之
二、浅拷贝和深拷贝结果
copy:拷贝的只要是不可变对象,都是浅拷贝,即指针拷贝,copy可变集合对象则是单层深拷贝,拷贝可变的非集合对象则是深拷贝
mutableCopy:拷贝集合象则是单层深拷贝,拷贝非集合对象则是深拷贝
不可变对象 | 可变对象 | 不可变集合 | 可变集合 | |
---|---|---|---|---|
copy | 浅拷贝 | 深拷贝 | 浅拷贝 | 单层深拷贝 |
mutableCopy | 深拷贝 | 深拷贝 | 单层深拷贝 | 单层深拷贝 |
三、集合的完全深拷贝 (deep copy)
集合的深复制有两种方法。可以用 initWithArray:copyItems: 将第二个参数设置为YES即可深复制,如
[[NSDictionary alloc] initWithDictionary:@{} copyItems:YES];
[[NSMutableDictionary alloc] initWithDictionary:@{} copyItems:YES];
[[NSArray alloc] initWithArray:@{} copyItems:YES];
[[NSMutableArray alloc] initWithArray:@{} copyItems:YES];
如果你用这种方法深复制,集合里的每个对象都会收到 copyWithZone: 消息。如果集合里的对象遵循 NSCopying 协议,那么对象就会被深复制到新的集合。如果对象没有遵循 NSCopying 协议,而尝试用这种方法进行深复制,会在运行时出错。copyWithZone: 这种拷贝方式只能够提供一层内存拷贝(one-level-deep copy),而非真正的深复制。
第二个方法是将集合进行归档(archive),然后解档(unarchive),如:
NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:oldArray]];
推荐参考博客
iOS 集合的深复制与浅复制