#warning 对于系统的非容器类对象,我们可以认为,如果对一不可变对象复制,copy是指针复制(浅拷贝)和mutableCopy就是对象复制(深拷贝)返回对象是否可变则根据接收的copystr来判断。如果是对可变对象复制,都是深拷贝,但是copy返回的对象是不可变的。
//1.对于不可变非容器类进行copy复制--浅拷贝且返回不可变字符串
// NSString *str = @"abc";
// NSString *copystr = [str copy];
// NSLog(@"str的引用计数是:%lu|str的地址是:%p|copystr的引用计数是:%lu|copystr的地址是:%p",[str retainCount],str,[copystr retainCount],copystr);
2.对于不可变非容器类进行Mutable拷贝--深拷贝且返回可变字符串(返回是否可变则根据copystr是可变还是不可变来判断)
// NSString *str = @"abc";
// NSMutableArray *copystr = [str mutableCopy];
// NSLog(@"str的引用计数是:%lu|str的地址是:%p|copystr的引用计数是:%lu|copystr的地址是:%p",[str retainCount],str,[copystr retainCount],copystr);
//3.对于可变非容器类进行copy拷贝--深拷贝且返回不可变字符串
// NSMutableString *str = [[NSMutableString alloc]initWithCapacity:0];
// [str appendFormat:@"abc"];
// NSMutableString *copystr = [str copy];
// NSLog(@"str的引用计数是:%lu|str的地址是:%p|copystr的引用计数是:%lu|copystr的地址是:%p",[str retainCount],str,[copystr retainCount],copystr);//此时copystr变为了不可变字符串,并且地址与str不同,所以为深拷贝
//4.对于可变对象进行mutablecopy拷贝--深拷贝且返回可变字符串
// NSMutableString *str = [[NSMutableString alloc]initWithCapacity:0];
// [str appendFormat:@"abc"];
// NSMutableString *copystr = [str mutableCopy];
// NSLog(@"str的引用计数是:%lu|str的地址是:%p|copystr的引用计数是:%lu|copystr的地址是:%p",[str retainCount],str,[copystr retainCount],copystr);//此时的copystr是可变数组,值可改变,而且地址与改值之前不变,地址与str完全不同,引用计数为1,所以是深拷贝
//此时推断copy和Mutablecopy的内部实现分2种情况,NSString和NSMutablestring
/*NSString:
- (id)copywithZone:(NSZone*)zone{
return self;
}
- (id)mutableCopywithZone:(NSZone*)zone{
NSMutableString* copy =[[NSMutableString alloc] initxxxxxx];
....
return copy;
}
NSMutableString:
- (id)copywithZone:(NSZone*)zone{
NSString* copy = [[NSStringalloc] initxxxxxx];
....
return copy;//所以不可修改
}
- (id)mutableCopywithZone:(NSZone*)zone{
NSMutableString* copy =[[NSMutableString alloc] initxxxxxx];
....
return copy;
}
---------------------------------------------------------以上为非容器类字符串的测试和推断---------------------------------------------------- */
接下来是容器类判断,苹果文档给出了3个概念
1.Making a shallow copy(浅拷贝)
2.Listing 2 Making a deep copy(深拷贝)
3.Listing 3 A true deep copy(完全深度拷贝)
//1.不可变容器类进行copy拷贝----浅拷贝且返回不可变数组
//NSArray *arr = [[NSArray alloc]initWithObjects:@"2",@"3",@"4",@"5", nil];
//NSArray *copyarr = [arr copy];
//NSLog(@"arr的引用计数是%lu|arr的地址是%p|copyarr的引用计数是%lu|copyarr的地址是%p",[arr retainCount],arr,[copyarr retainCount],copyarr);//此时地址相同,引用计数相同,为浅拷贝
//2.不可变容器类进行mutablecopy拷贝--深拷贝且返回不可变数组
//NSArray *arr = [[NSArray alloc]initWithObjects:@"2",@"3",@"4",@"5", nil];
//NSArray *copyarr = [arr mutableCopy];
//NSLog(@"arr的引用计数是%lu|arr的地址是%p|copyarr的引用计数是%lu|copyarr的地址是%p",[arr retainCount],arr,[copyarr retainCount],copyarr);//此时地址不同,引用计数都是1,所以是浅拷贝
// NSLog(@"%p %p",copyarr[0],arr[0]);//虽然数组地址不同,但是内的元素地址相同
//3.可变容器类进行copy拷贝---深拷贝且返回不可变数组
// NSMutableArray *arr = [[NSMutableArray alloc]initWithObjects:@"2",@"3",@"4",@"5", nil];
// NSMutableArray *copyarr = [arr copy];
// NSLog(@"arr的引用计数是%lu|arr的地址是%p|copyarr的引用计数是%lu|copyarr的地址是%p",[arr retainCount],arr,[copyarr retainCount],copyarr);//此时地址不同,引用计数都是1,所以是浅拷贝
// NSLog(@"%p %p",copyarr[0],arr[0]);//虽然数组地址不同,但是内的元素地址相同
//4.可变容器类进行mutable拷贝---深拷贝且返回可变数组
// NSMutableArray *arr = [[NSMutableArray alloc]initWithObjects:@"2",@"3",@"4",@"5", nil];
// NSMutableArray *copyarr = [arr mutableCopy];
// NSLog(@"arr的引用计数是%lu|arr的地址是%p|copyarr的引用计数是%lu|copyarr的地址是%p",[arr retainCount],arr,[copyarr retainCount],copyarr);//此时地址不同,引用计数都是1,所以是深度拷贝
// NSLog(@"%p %p",copyarr[0],arr[0]);//虽然数组地址不同,但是内的元素地址相同
// NSLog(@"%lu %lu",[copyarr[0] retainCount],[arr[0] retainCount]);
由此可见TrueDeepCopy没有在上述出现,
浅拷贝:直接复制数组指针
深拷贝:直接复制数组的内容,这里可以直接使用mutableCopy方法进行实现.
可见容器类的深浅拷贝和非容器类的概念是一样的,如果把容器内的每个元素都看作一个整体来理解
而TrueDeepCopy则由下述代码实现
NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"a",nil];
NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:
[NSKeyedArchiver archivedDataWithRootObject: array]];
http://blog.csdn.net/kissing_huo/article/details/37050603
而当自定义拷贝时需要自己开写CopyZone并且遵守copy的协议
- (id)copyWithZone:(nullableNSZone *)zone{
//浅拷贝
// return [self retain];
//深拷贝
// Person *copyPer = [[Person allocWithZone:zone]init];
// copyPer.name = self.name;
// return copyPer;
//完全深度深拷贝
// Person *copyPer = [[Person allocWithZone:zone]init];
// copyPer.name = [self.name mutableCopy];
// return copyPer;
}