深拷贝与浅拷贝(iOS 篇)
前言
关于拷贝,小到面试题,大到找不出 Bugs。
在 iOS 中分为 浅拷贝 和 深拷贝,对应 Foundation 中的基本数据类型,系统已经实现和遵循了 NSCopying 协议和方法。下面大家来了解一下。
深拷贝与浅拷贝
1 | @protocol NSCopying |
区别:
浅拷贝:指针拷贝,共用一个内存地址。
深拷贝:新的指针,新的内存地址。
不可变对象进行 copy, 不会生成新的对象(类型:eg:NSString),共用一个地址。
可变对对象进行 copy, 会生成新的对象(类型:eg:NSMutableString),新的内存地址。1
2
3
4
5
6NSString * oldStr = @"older";
NSString * newStr = [oldStr copy];
NSLog(@"%p - %p - %@", oldStr, newStr, [oldStr class]);
oldStr = [oldStr stringByAppendingString:@"12"];//生成新的对象,并指向新的指针地址
NSLog(@"%@ - %@ - %@", oldStr, newStr, [newStr class]);
NSLog(@"%p - %p", oldStr, newStr);
1 | 0x1021e40d8 - 0x1021e40d8 - __NSCFConstantString |
1 | NSMutableString * oldMStr = [NSMutableString stringWithString:@"mutableStr"]; |
1 | 0x6000022297a0 - 0x600002c422e0 - __NSCFString |
不可变对象进行 mutableCopy, 会生成新的对象(类型:eg:NSMutableString),新的内存地址。
可变对象进行 mutableCopy, 会生成新的对象(类型:eg:NSMutableString),新的内存地址。1
2
3
4
5
6NSArray * oldArr = [NSArray arrayWithObject:@"array"];
NSArray * newArr = [oldArr mutableCopy];
NSLog(@"%p - %p - %@", oldArr, oldArr, [oldArr class]);
oldArr = [oldArr arrayByAddingObject:@"-arr"];//新的对象,新的内存地址
NSLog(@"%ld - %ld - %@", oldArr.count, newArr.count, [newArr class]);
NSLog(@"%p - %p", oldArr, newArr);
1 | 0x600002e73c50 - 0x600002e73c50 - __NSSingleObjectArrayI |
1 | NSMutableArray * oldMArr = [NSMutableArray arrayWithObject:@"mutableArray"]; |
1 | 0x600002229830 - 0x600002229e30 - __NSArrayM |
对于自定义对象,若要使用 copy 或 mutableCopy 需要遵循协议,实现协议方法。
知识点
Q: 在 property 中,为什么常用 copy 修饰 string 字符串,而不用 strong 修饰?
分析:首先 Strong 会指向内存地址,如果用 strong 修饰可变字符时,当指向的内存地址发生变化时,属性中的值也会相应变化;copy 修饰,相当于对象进行浅拷贝(self.obja = [objb copy])。
1 | @property (nonatomic, copy) NSString * string0; |
对应不可变的字符串来说,相当于浅拷贝,指针拷贝。1
2
3
4
5NSString * string0 = @"string0";
self.string0 = string0;
self.string1 = string0;
string0 = @"0";//指针地址发生变化
NSLog(@"%p, %p, %p", self.string0, self.string1, string0);
1 | 0x10c59c098, 0x10c59c098, 0x10c59c0b8 |
对应可变的字符串来说,copy 修饰相当于深拷贝,strong 修饰为指针拷贝。1
2@property (nonatomic, copy) NSMutableString * mString0;
@property (nonatomic, strong) NSMutableString * mString1;
1 | NSMutableString * pMstr = [NSMutableString stringWithString:@"string"]; |
1 | 0xdd890020b715b501, 0x600000ba9da0, 0x600000ba9da0 |
A:对应不可变的字符串来说,相当于浅拷贝,指针拷贝;对应可变的字符串来说,copy 修饰相当于深拷贝,strong 修饰为指针拷贝。若不想属性成员变量随着变化,请用 copy 修饰。
参考资料
文档信息
- 版权声明:自由转载-保持署名-非商用-非衍生 ( CC BY-NC-ND 4.0 )