深浅拷贝相信对于大多数iOS开发者而言并不陌生,写这篇文章的目的是在公司项目的开发中遇到的一个可变数组赋值问题所以专门总结下深浅拷贝的知识。
提要
本篇文章主要围绕以下几点来讲述:
1、深浅拷贝的概念
2、集合与非集合对象的深浅拷贝差异
3、一些Tips
拷贝前提
一个对象是否可以拷贝取决于该对象是否遵循NSCopying协议,并且实现copyWithZone:方法。如果一个类有可变和不可变类型,那么不可变类需要遵守NSMutableCopying协议,并且实现mutableCopyWithZone 方法确保被复制对象保持可变。
深浅拷贝的概念
图一@2x.png浅拷贝:指针拷贝,仅拷贝对象指针,对象内存地址并不发生改变。
图二@2x.png深拷贝:内容拷贝,完全复制一份对象,复制对象与旧对象内存地址不同。
集合与非集合对象的深浅拷贝
对于iOS中的对象来说,我们可以将其大致的分为集合对象(NSArray、NSSet等)和非集合对象(NSString、NSNumber等)。对于拷贝而言有如下几种情况。
1、不可变对象的拷贝操作
2、不可变对象的可变拷贝操作
3、可变对象的拷贝操作
4、可变对象的可变拷贝操作
非集合对象的深浅拷贝
图3@2x.png1、不可变对象的拷贝操作
打印结果
图4@2x.png
结论:不可变对象copy为浅复制,mutableCopy为深复制。
图五@2x.png2、可变对象的拷贝操作
打印结果
图六@2x.png结论:不可变对象copy与mutableCopy都是深复制
集合对象的深浅拷贝
集合对象深浅拷贝图解
图七@2x.png1、集合对象的浅复制
图八@2x.png对于集合来说有许多种方法来实现浅复制。当进行浅复制的时候,会向原始对象发送一个retain消息,同时指针会指向新的集合。
2、集合对象的深复制
图九@2x.png方式一
需要将第二个参数设置为yes。
图十@2x.png方式二
复制与可变性
当复制一个集合对象的时候,集合对象本身和集合所包含元素的可变性会受到影响。
copyWithZone: 仅使表层集合对象不可变,集合内部对象仍保持原有状态.
initWithArray:copyItems:第二个参数为NO时,表明该类创建时的表层可变性保持其初始值。更深层元素保持元其原有的可变性。
归档解档集合使得对象的可变与之前完全不同。
3、不可变集合对象的copy与mutableCopy
图十一@2x.png结果:
图十二@2x.png结论: 不可变集合对象copy为浅复制,mutableCopy为深复制
4、可变集合对象的copy与mutableCopy
图十三@2x.png结果:
图十四@2x.png结论:可变集合对象的copy与mutableCopy都是深复制。
一些tips
1、对于包含可变类型的类来说例如NSString,建议在写property时使用copy关键字,保护封装性。
2、对于从外部传入的数组,在函数内部对其进行拷贝操作,保证外部对数组的操作不会影响内部的。
3、等号直接赋值为浅复制。
希望以上总结对各位读者有所帮助。因个人能力所限,如果错误及纰漏还请广大读者批评指正。
网友评论