iOS 深复制&浅复制
![](https://images0.cnblogs.com/blog2015/351007/201507/091619177684401.jpg)
1、无论是深复制还是浅复制,被复制的对象类型是不变的。此对象类型具有什么功能就具有什么功能,不会因为自行修改了返回对象的指针类型而改变。
比如:
![](https://images0.cnblogs.com/blog2015/351007/201507/091619255969309.jpg)
这里的str和str1的值和指针地址完全一样,因为是不可变类型使用了copy,什么都不变。为什么NSNumber类型的指针可以指向NSSring类型copy出的对象呢?因为copy返回类型为id万能指针类型。如果返回的是instancetype就会警告。
记住:对于不可变的临时变量使用浅复制copy没什么用,地址和值都一样。
2、怎么理解最后一句话?
临时变量是方法或者函数体里面声明的一个变量,比如读取plist文件到一个可变的NSMutableArray类型的arrayM,这个arrayM就是一个可变的临时变量。当数据组织完成后需要赋值给类的成员变量,比如有个不可变的NSArray类型的array,这个array就是一个不可变的成员变量,下面这样做比较安全:self.array = [arrayM copy];
另外,如果这个成员变量是NSString的话,在使用set方法的时候要用copy
![](https://images0.cnblogs.com/blog2015/351007/201507/091619348775973.png)
上面说的都是OC的基本对象类型的深复制和浅复制。
==============================================
下面说一下自定义OC类对象及其子类对象的深复制和浅复制
比如一个Person类,及其子类Student
1、父类遵循<NSCoping>协议
![](https://images0.cnblogs.com/blog2015/351007/201507/091619440493138.jpg)
2、父类实现copyWithZone:方法
![](https://images0.cnblogs.com/blog2015/351007/201507/091619497689891.jpg)
3、子类Student继承父类Person,自动继承了<NSCopying>协议
![](https://images0.cnblogs.com/blog2015/351007/201507/091620105183819.jpg)
4、子类Student重写父类的copyWithZone:方法
![](https://images0.cnblogs.com/blog2015/351007/201507/091620252681780.jpg)
*********************************************************************
![](https://images0.cnblogs.com/blog2015/351007/201507/091620322993331.jpg)
问题一:
如果父类的[self class]换成了父类Person本身类型会有什么问题?
上面说过虽然copy的返回值类型是id类型的,任何类型的指针都可以指向copy堆中后的对象,但不具有什么功能方法始终不具备什么功能方法。这里虽然Student类型的指针s1指向了Person的copy后的对象,但Person的copyWithZone:方法是Person类自身的复制,所以s1指针的Person类型的对象,而Person类没有No成员变量,所以会找不到方法。报如下常见错误:
![](https://images0.cnblogs.com/blog2015/351007/201507/091620459089505.jpg)
问题二:
如果在copyWithZone:中少写了某个或某些成员变量的赋值,会有什么结果?
结果就是未被赋值的成员变量将保持该成员变量类型的默认值。比如,Person里面少赋值了一个age成员变量,Student对象在copy的时候访问age变量得到的值为0,而不是1000.如上图调试所示。
////////////////////////////////////////////////////////////////////////
另:iOS里的[self class]就等同于C#中的T