- 目的: 建立一个副本,彼此修改,各不干扰
- 作用: 利用一个源文件(源对象)产生一个副本文件(对象)
- 实现拷贝的方法有2个:
copy
:返回不可变副本,mutableCopy
:返回可变副本
NSDictionary *dict = @{@"name" : @"Jerry"};
[dict copy] --> 拷贝出内容与dict相同的NSDictionary类型的字典
[dict mutableCopy] --> 拷贝出内容与dict相同的NSMutableDictionary类型的字典 - 普通对象实现拷贝的步骤
- 1.遵守NSCopying协议
- 2.实现-copyWithZone:方法
- 3.创建新对象
- 4.给新对象的属性赋值
拷贝两种方式
-
浅拷贝(指针拷贝)
- 对于浅拷贝来说,仅仅是拷贝指向对象的指针,拷贝出来的对象与源对象
地址一致
,A 和 [A copy] 指向的是同一个内存资源,拷贝的只不过是是一个指针,这意味着我修改拷贝对象的值会直接影响到源对象。
- 对于浅拷贝来说,仅仅是拷贝指向对象的指针,拷贝出来的对象与源对象
-
深拷贝(内容拷贝)
- 拷贝出来的对象与源对象
地址不一致
,内存中存在了两份独立对象本身(即深拷贝产生了新对象),这意味着我修改拷贝对象的值对源对象的值没有任何影响 - 对于NSString对象, 确实深拷贝就是深拷贝, 浅拷贝就是浅拷贝, 没有任何异议。 但是对于NSArray, NSDictionary, NSSet这些容器类的对象则有两种情况:
不完全深拷贝
和完全深拷贝
。 - 默认状态下深拷贝指的是不完全深拷贝, 如要实现完全深拷贝, 则要重写
copyWithZone:
方法, 自行实现完全深拷贝的需求. 大体思路如下, 在copyWithZone: 里对象赋值上不直接赋值而是通过copy方法即可实现。
- 拷贝出来的对象与源对象
-
深拷贝之
不完全深拷贝
- 不完全深拷贝就是只拷贝容器对象(拷贝一个壳), 而对于容易内的对象则只保存一份引用
-
下图,就算我们修改copyArray不会影响到源array, 但是我通过copyArray修改数组内的object, 对应地源array内的object也会随之修改
不完全深拷贝
-
深拷贝之
完全深拷贝
- 完全深拷贝就是连同容器内的对象在内, 完完全全拷贝一份出来
-
通过图片可以很清楚地知道, 这种情况下无论是修改copyArray还是通过copyArray修改数组内的object, 对源array都不会造成半点影响.
完全深拷贝
自定义对象的@property 中加copy
- 它自动生成的set方法是:
- (void)setxxx:(类:)xxx {
_xxx = [xxx copy];
}
最后肯定会崩,理由是找不到copyWithZone这个方法
网友评论