一、深浅复制的概念
**浅复制:之复制对象内实例变量的指针地址,而不是真正复制这个对象的复制叫做浅复制;
深复制:不仅复制对象本身,而且会递归地去复制每个指针类型的实例变量,一直到两个对象不再共享任何共用部分;**
二、深浅复制的写法示例
深复制的写法:
假设这里有一个类叫做Book,类中的变量有 name书名(NSString) 和 price价格(double) , 所有复制需要是深复制
- (id) copyWithZone: (NSZone*) zone
{
//使用zone参数创建对象
Book* book = [[[self class] allocWithZone: zone] init];
//将原有对象的name变量复制一份可修改的副本赋值给新对象
book.name = [self.name mutableCopy];
book.price = self.price;
return book;
}
在上面的代码中,如果把book.name属性赋值的语句的右值直接写成:self.name 的话, 就是浅复制的实现了,它会复制一个同样指向原来书名的NSString*给book.name。原对象或者book任意一个改变了name的值,都会引起另一个的值改变。
一般来说,深复制的难度是比较大的,尤其是一个对象包含了大量的指针类型变量时,如果某些指针变量指向的实例又包含了指针变量,那么深拷贝的实现会变得更加复杂一些。
Foundation框架中的大多数类都只是实现了浅复制。
注:
这里要重新提一下settter方法中的复制选项:
例如:
@interface Book: NSObject
@propetry (nonatomic, copy) NSMutableString* name;
@end
只要一个类中的实例变量的setter复制选项被声明为copy,那么在对这个变量赋值的时候,调用的方法是[传入的name参数 copy]方法,该方法返回的结果是一个不可变的副本。这会误导一部分的人:“为什么我声明的是可变类型的字符串,但是运行时还是会在改变这个实例变量的地方出错?“ 根本原因就是setter选项设置的问题,所以在这里一定要小心取舍到底是不是要声明称为copy选项。
另外,合成setter和getter都没有提供mutableCopy选项。