一、深拷贝和浅拷贝
1.浅拷贝:也可以叫影子拷贝或者指针拷贝,浅拷贝就是对内存地址的复制,会生成一个新的指针指向这块内存地址.
浅拷贝就是拷贝指向原来对象的指针,是对象的引用计数+1,可以理解为创建了一个新的指向原来对象的指针而已,并没有开辟新的内存空间.这就例如用一间房间的钥匙A配了一枚新的钥匙B,两枚钥匙能且仅能开这间房子的钥匙.
2.深拷贝:深拷贝是指拷贝对象的具体内容,会生成一块新的内存空间来存放一个新的对象,虽然两个对象的值是一样的,但是内存地址是不一样的.
深拷贝就是重生成一个值和原来对象一模一样的新对象,拷贝后两者内有什么关系,互不影响,互不干涉.这就例如:仿照A房间的样式新建了B房间一样.
3.总结:浅拷贝就是指针拷贝,深拷贝就是内容拷贝.本质区别在于:
·是否影响原来对象的引用计数
·是否开辟新的内存空间,即是否生成新的对象
二、copy和mutableCopy
1、非集合对象的copy与mutableCopy
1.1 不可变对象NSString
NSString的copy是浅拷贝,且copy返回的对象是不可变对象;mutableCopy是深拷贝。
1.2 可变对象NSMutableString
NSMutableString对象copy与mutableCopy都是深拷贝,且copy返回的对象是不可变对象。
2、集合对象的copy与mutableCopy
2.1 不可变对象NSArray
NSArray的copy是浅拷贝,且copy返回的对象是不可变对象;mutableCopy是深拷贝。
2.2 可变对象NSMutableArray
NSMutableArray对象copy与mutableCopy都是深拷贝,且copy返回的对象是不可变对象。
特别注意的是:对于集合类的可变对象来说,深拷贝并非严格意义上的深复制,只能算是单层深复制,即虽然新开辟了内存地址,但是存放在内存上的值(也就是数组里的元素仍然之乡员数组元素值,并没有另外复制一份),这就叫做单层深复制。
2.3集合对象的完全深拷贝
2.2中提到了集合类的对象来说,深拷贝只是单层深拷贝,那有没有办法实现每一层都深拷贝呢?回答是肯定的,目前我们可以这么做:
(1)归档解档大法
- (void) deplyFullCopy
{
NSMutableArray *marry1 = [[NSMutableArray alloc] init];
NSMutableString *mstr1 = [[NSMutableString alloc]initWithString:@"value1"];
NSMutableString *mstr2 = [[NSMutableString alloc]initWithString:@"value2"];
[marry1 addObject:mstr1];
[marry1 addObject:mstr2];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:marry1];
NSArray *marray2 = [NSKeyedUnarchiver unarchiveTopLevelObjectWithData:data error:nil];
}
(2)- (instancetype)initWithArray:(NSArray<ObjectType> *)array copyItems:(BOOL)flag;
复制代码
- (void) deplyFullCopy2
{
NSMutableArray *marry1 = [[NSMutableArray alloc] init];
NSMutableString *mstr1 = [[NSMutableString alloc]initWithString:@"value1"];
NSMutableString *mstr2 = [[NSMutableString alloc]initWithString:@"value2"];
[marry1 addObject:mstr1];
[marry1 addObject:mstr2];
NSArray *marray2 = [[NSArray alloc] initWithArray:marry1 copyItems:YES];
}
3.总结:
NO1:可变对象的copy和mutableCopy都是深拷贝
NO2:不可变对象的copy方法是浅拷贝,mutableCopy方法是深拷贝
NO3.copy方法返回的对象都是不可变对象.
NO4.copy≠浅拷贝,mutableCopy≠深拷贝