关于非容器类和容器类深浅拷贝的区分

#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,所以是深拷贝






//此时推断copyMutablecopy的内部实现分2种情况,NSStringNSMutablestring   

/*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;

}







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值