copy 老生常谈了。估计是个iOS开发者都知道这事。
这篇文章就稍微全面写一写。 原文章 传送门
1、系统对象的copy与mutableCopy
NSObject
类提供了copy
和mutableCopy
方法,通过这两个方法即可复制已有对象的副本,本文将会详细介绍关于对象复制的内容。
copy方法用于复制对象的副本。
通常来说,copy
方法总是返回对象的不可修改的副本,即使对象本身是可修改的。
例如,程序调用NSMutableString
的copy
方法,将会返回不可修改的字符串对象,
mutableCopy方法用于复制对象的可变副本。
通常来说,mutableCopy
方法总是返回对象可修改的副本,即使被复制的对象本身是不可修改的,调用mutableCopy
方法复制出来的副本也是可修改的。
例如,程序调用NSString
的mutableCopy
方法,将会返回一个NSMutableString
对象。
下图详细阐述了NSString
、NSMutableString
、NSArray
、NSMutableArray
、NSDictionary
、NSMutableDictionary
分别调用copy
与mutableCopy
方法后的结果:
2、深复制与浅复制
对象拷贝有两种方式:浅复制和深复制。
顾名思义,浅复制,并不拷贝对象本身,仅仅是拷贝指向对象的指针;
深复制是直接拷贝整个对象内容到另一块内存中。
再简单些说:浅复制就是指针拷贝;深复制就是内容拷贝。
如果在多层数组中,对第一层进行内容拷贝,其它层进行指针拷贝,这种情况是属于深复制,还是浅复制?对此,苹果官网文档有这样一句话描述:
This kind of copy is only capable of producing a one-level-deep copy. If you only need a one-level-deep copy…
If you need a true deep copy, such as when you have an array of arrays…
从文中可以看出,苹果认为这种复制不是真正的深复制,而是将其称为单层深复制(one-level-deep copy)。因此,有人对浅复制
、完全深复制
、单层深复制
做了概念区分。
当然,这些都是概念性的东西,没有必要纠结于此。只要知道进行拷贝操作时,被拷贝的是指针还是内容即可。
一般来说,完全深复制的实现难度大很多,尤其是当该对象包含大量的指针类型的实例变量时,如果某些实例变量里再次包含指针类型的实例变量,那么实现完全深复制会更加复杂。
上面图中的深复制(单层或者完全)就是因为集合对象中可能会包含指针类型的实例变量,从而导致深复制不完全。
3、自定义对象的复制
使用copy
和mutableCopy
复制对象的副本