iOS 浅赋值、深复制、完全复制的知识点梳理验证(附加归档解档)
2016-08-13 13:45
495 查看
转载请注明出处http://blog.csdn.net/zsk_zane
(单层和完全概念区分:例如多层数组只实现一层内容拷贝,其他层为指针拷贝成为单层深复制;若多层内容都实现拷贝称为完全赋值)
浅复制(shallow copy):在浅复制操作时,对于被复制对象的每一层都是指针复制。
深复制(one-level-deep copy):在深复制操作时,对于被复制对象,至少有一层是深复制。
完全复制(real-deep copy):在完全复制操作时,对于被复制对象的每一层都是对象复制。
(2)
归档和解档的概念补充:
有时存在这样的需求,即将程序中使用的多个对象及其属性值,以及它们的相互关系保存到文件中,或者发送给另外的进程。为了实现此功能,foundation框架中,可以把相互关联的多个对象归档为二进制文件,而且还能将对象的关系从二进制文件中还原出来。
归档:将对象打包成二进制文件。NSKeyedArchiver:归档器
解档:归档的逆变换。NSKeyedUnarchiver:解档器
因此可以利用归档和解档来实现完全复制
输出结果:
从上述打印地址可以看出:
浅复制只是简单的指针赋值,指向内存仍相同;
深复制,和完全深复制都实现了内容的复制,但是是否实现对被复制对象的每一层都复制,通过查看多层数组第二层元素的地址来验证:
输出结果:
深复制地址也相同,就说明第二层元素并没有实现内容拷贝,证实iOS中的深复制只实现了单层复制
完全复制地址不同,说明归档解档方法实现的完全复制其每一层都实现内容拷贝
数组中如果对象为自定义对象,默认没有实现NSCopying协议,拷贝会出错。
如果想正常拷贝,自定义对象类需实现NSCopying协议,重写copyWithZone方法。
写于前:
在之前转载的一片文章中,文中对浅复制和深复制进行了详细的解读,同时还提到了深复制(one-level-deep copy)、完全复制(true copy)的概念,并指出iOS开发中的深复制是单层深赋值,本文将对这几个概念进行验证梳理。(单层和完全概念区分:例如多层数组只实现一层内容拷贝,其他层为指针拷贝成为单层深复制;若多层内容都实现拷贝称为完全赋值)
程序中用到的几点概念补充
(1)浅复制(shallow copy):在浅复制操作时,对于被复制对象的每一层都是指针复制。
深复制(one-level-deep copy):在深复制操作时,对于被复制对象,至少有一层是深复制。
完全复制(real-deep copy):在完全复制操作时,对于被复制对象的每一层都是对象复制。
(2)
归档和解档的概念补充:
有时存在这样的需求,即将程序中使用的多个对象及其属性值,以及它们的相互关系保存到文件中,或者发送给另外的进程。为了实现此功能,foundation框架中,可以把相互关联的多个对象归档为二进制文件,而且还能将对象的关系从二进制文件中还原出来。
归档:将对象打包成二进制文件。NSKeyedArchiver:归档器
解档:归档的逆变换。NSKeyedUnarchiver:解档器
因此可以利用归档和解档来实现完全复制
代码验证
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//创建多层数组</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSArray</span> *array = @[@<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>,@<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>]; <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSArray</span> *oldArray = @[@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"xxxx"</span>,array]; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//浅复制</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSArray</span> *shallowArray = [oldArray copy]; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//深复制</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSArray</span> *oneDeepLevelArray = [oldArray mutableCopy]; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//完全深复制,利用归档和解档的方式</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSArray</span> *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:oldArray]];</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>
<code class="hljs mel has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> NSLog(<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@"</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">%p</span>,<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">%p</span>,<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">%p</span>,<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">%p</span><span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">",oldArray,shallowArray,oneDeepLevelArray,trueDeepCopyArray);</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
输出结果:
<code class="hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">0x7fc7e9c1c0d0,0x7fc7e9c1c0d0,0x7fc7e9c0c5c0,0x7fc7e9c22ef0</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
从上述打印地址可以看出:
浅复制只是简单的指针赋值,指向内存仍相同;
深复制,和完全深复制都实现了内容的复制,但是是否实现对被复制对象的每一层都复制,通过查看多层数组第二层元素的地址来验证:
<code class="hljs perl has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> NSLog(<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@"</span>shallow——<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">%p</span>,<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">%p</span><span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">",oldArray[1][0],shallowArray[1][0]); NSLog(<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@"</span>oneDeep——<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">%p</span>,<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">%p</span>"</span>,oldArray[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>][<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>],oneDeepLevelArray[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>][<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]); NSLog(<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@"</span>trueDeep——<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">%p</span>,<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">%p</span><span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">",oldArray[1][0],trueDeepCopyArray[1][0]); </span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>
输出结果:
<code class="hljs bash has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> shallow——<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>xb000000000000012,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>xb000000000000012 oneDeep——<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>xb000000000000012,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>xb000000000000012 <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>Deep——<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>xb000000000000012,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>xb000000000000013</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>
结论
浅复制地址相同,这点毫无疑问深复制地址也相同,就说明第二层元素并没有实现内容拷贝,证实iOS中的深复制只实现了单层复制
完全复制地址不同,说明归档解档方法实现的完全复制其每一层都实现内容拷贝
附注:
数组中如果对象为自定义对象,默认没有实现NSCopying协议,拷贝会出错。如果想正常拷贝,自定义对象类需实现NSCopying协议,重写copyWithZone方法。
相关文章推荐
- iOS 浅赋值、深复制、完全复制的知识点梳理验证(附加归档解档)
- iOS 浅赋值、深复制、全然复制的知识点梳理验证(附加归档解档)
- 互联网公司iOS开发工程师面试必看(最全知识点梳理)
- iOS 完全复制UIView
- iOS 数据的归档(NSKeyedArchiver )与数据的解档(NSKeyedUnarchiver) 加密 提高安全性
- iOS 完全复制UIView
- iOS 对象的归档、解档 runtime
- ios:NSKeyedArchiver/NSKeyedUnarchiver(归档/解档)
- iOS 完全复制UIView
- iOS 解档归档
- iOS 归档 解档使用总结
- IOS数据存储之归档/解档
- iOS 自定义的对象类型的解档和归档
- IOS 利用运行时机制来进行归档解档
- iOS 完全复制UIView
- iOS-数据源存储方式三之归档、解档
- iOS swift-归档与解档
- iOS知识点全梳理-b
- ios- 归档 解档
- iOS 复制知识点总结