copy&mutablecopy

copy&mutablecopy

深拷贝(单层深拷贝/完全深拷贝) & 浅拷贝

浅拷贝:指针复制,源对象和副本指向的同一个内容(同一块内存),只有引用计数改变

深拷贝:内容复制,源对象和副本指向的是两块不同的内存,源对象引用计数不变,副本对象的引用计数为1

单层拷贝:针对集合,只对集合中的第一层元素进行copy操作(可能存在数组嵌套数组。。。)

完全拷贝:对集合中的每一层都执行copy操作

在OC中只有遵守NSCopyingNSMutableCopying协议的对象才能使用copy或mutablecopy,对象是进行深拷贝还是浅拷贝具体看协议方法是如何实现的

 @protocol NSCopying
 
 - (id)copyWithZone:(nullable NSZone *)zone;
 
 @end
 
 @protocol NSMutableCopying
 
 - (id)mutableCopyWithZone:(nullable NSZone *)zone;
 
 @end

非容器类的copy、mutablecopy

1.不可变对象copy

NSString *str = @"hello";

NSString *strCopy = str.copy;

NSLog(@"%p, %p", str, strCopy);

打印结果:0x106d3e068, 0x106d3e068

2.不可变对象mutablecopy

NSString *str = @"leeyii";

NSMutableString *mCopyStr = str.mutableCopy;

NSLog(@"%p, %p", str, mCopyStr);

[mCopyStr appendString:@"111"];

打印结果:0x106d3e0a8, 0x61800006ba40

3.可变对象copy

NSMutableString *mStr = @"lilei".mutableCopy;

NSString *copyMstr = mStr.copy;

NSLog(@"%p, %p", mStr, copyMstr);

打印结果:0x608000069e40, 0xa000069656c696c5

4.可变对象mutablecopy

NSMutableString *mStr = @"lilei".mutableCopy;

NSMutableString *mcopyMstr = mStr.mutableCopy;

NSLog(@"%p, %p", mStr, mcopyMstr);

打印结果:0x608000069e40, 0x60800006a240

结论:只有不可变对象进行copy是浅拷贝,其余都是深拷贝

  • 容器类copy/mutablecoy

与非容器类类似,只有不可变对象进行copy时是浅拷贝,其余操作全部是深拷贝。

但对容器内的元素进行拷贝时,全部是浅拷贝(指针指向的内容不变)

如果要对集合内的元素也进行拷贝,用下面这个方法。
NSArray *deepCopy = [[NSArray alloc] initWithArray:arr copyItems:YES];
如果你用这种方法拷贝,集合里的每个对象都会收到 copyWithZone: 消息。如果集合里的对象都遵循 NSCopying 协议,那么对象就会被拷贝到新的集合。如果对象没有遵循 NSCopying 协议,而尝试用这种方法进行深拷贝,会在运行时出错。copyWithZone: 这种拷贝方式只能够提供一层内存拷贝(one-level-deep copy),而非真正的深拷贝。

如果要进行完全拷贝可以使用下面的方法
NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:oldArray]];

参考文档

iOS 集合的深拷贝与浅拷贝

转载于:https://www.cnblogs.com/leeyii/p/6612261.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值