ios开发详细解析copy和mutableCopy
在日常开发中,很多时候都会用到copy和mutableCopy,但是大家是否真正了解copy过程中内存发生了什么?copy是深拷贝还是浅拷贝呢?什么时候用copy?什么时候用mutableCopy?有什么区别?
Keynote画的....探索前我们需要知道
浅复制:仅仅是拷贝指向对象的指针,并不拷贝对象本身(左图)
深复制:直接拷贝整个对象内存到另一块内存中(右图)
注意:使用copy/mutableCopy,类必须实现NSCopying协议/NSMutableCopying协议
我们先看看官方文档怎么说的copy(截取重要的一部分)
The exact meaning of “copy” can vary from class to class, but a copy must be a functionally independent object with values identical to the original at the time the copy was made. A copy produced with NSCopying is implicitly retained by the sender, who is responsible for releasing it....
注意重点(加粗斜体),大概意思为:副本对象必须是一个功能独立的对象,其值与复制时的原始值相同
也就是说:副本对象是独立的,修改源对象/副本对象的属性和行为,不会影响副本对象/源对象.
简单来讲就是copy之后的对象,与源对象互不影响
然后我们要知道copy:创建的是不可变副本(NSString,NSArray,NSDictionary)
mutableCopy:创建的是可变副本(NSMutableString,NSMutableArray,NSMutableDictionary)
接下来是例子:
NSString *str = @"你好!";
NSMutableString *mutableStr = [str mutableCopy];
NSLog(@"%@,%p",str,str);
NSLog(@"%@,%p",mutableStr,mutableStr);
打印结果:
2018-05-02 11:54:11.415754+0800 demo[2025:206958] 你好!,0x109b75068
2018-05-02 11:54:11.415926+0800 demo[2025:206958] 你好!,0x60c00005ee70
很明显,两个对象的内容一样,但是地址不一样
上面已经说了,copy后的副本对象功能独立,对其修改不能影响源对象,所以理所应当,必须生成一个新的对象.
难道每次都会生成一个新的对象么?每次都是深拷贝么?
当然不是,我们再看一个例子:
NSString *str1 = @"你好!";
NSString*str2 = [str1copy];
NSLog(@"%@,%p",str1,str1);
NSLog(@"%@,%p",str2,str2);
打印结果:
2018-05-02 11:36:20.889907+0800 demo[1983:184598] 你好!,0x1057a1068
2018-05-02 11:36:20.890134+0800 demo[1983:184598] 你好!,0x1057a1068
注意,两个对象的内存地址是一样的,也就是说系统并没有创建一个新对象
分析:当NSString类型的对象(不可变)经过copy后,拷贝出来的对象也是NSString类型,也是不可变的.既然两者都是不可改变的, 那么一定不会互相影响,换句话说一定是功能独立的,所以系统不会产生新的对象了
总结一下,关于copy是深拷贝?浅拷贝?是否创建新的对象?这些都是由程序运行的环境所造成的,并不是一概而论。