iOS 浅复制、深复制、完全复制的知识点梳理验证(附加归档解档)

在之前转载的一片文章中,文中对浅复制和深复制进行了详细的解读,同时还提到了深复制(one-level-deep copy)、完全复制(true copy)的概念,并指出iOS开发中的深复制是单层深赋值,本文将对这几个概念进行验证梳理。

(单层和完全概念区分:例如多层数组只实现一层内容拷贝,其他层为指针拷贝成为单层深复制;若多层内容都实现拷贝称为完全复制)

 

程序中用到的几点概念补充

(1)

浅复制(shallow copy):在浅复制操作时,对于被复制对象的每一层都是指针复制。 
深复制(one-level-deep copy):在深复制操作时,对于被复制对象,至少有一层是深复制。 
完全复制(real-deep copy):在完全复制操作时,对于被复制对象的每一层都是对象复制。

(2)

归档和解档的概念补充: 
有时存在这样的需求,即将程序中使用的多个对象及其属性值,以及它们的相互关系保存到文件中,或者发送给另外的进程。为了实现此功能,foundation框架中,可以把相互关联的多个对象归档为二进制文件,而且还能将对象的关系从二进制文件中还原出来。

 

归档:将对象打包成二进制文件。NSKeyedArchiver:归档器 
解档:归档的逆变换。NSKeyedUnarchiver:解档器 
因此可以利用归档和解档来实现完全复制

代码验证

    //创建多层数组
    NSArray *array = @[@1,@2];
    NSArray *oldArray = @[@"xxxx",array];

    //浅复制
    NSArray *shallowArray = [oldArray copy];
    //深复制
    NSArray *oneDeepLevelArray = [oldArray mutableCopy];
    //完全深复制,利用归档和解档的方式
    NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:oldArray]];
    NSLog(@"%p,%p,%p,%p",oldArray,shallowArray,oneDeepLevelArray,trueDeepCopyArray);

输出结果:

0x7fc7e9c1c0d0,0x7fc7e9c1c0d0,0x7fc7e9c0c5c0,0x7fc7e9c22ef0

从上述打印地址可以看出:

浅复制只是简单的指针赋值,指向内存仍相同; 
深复制,和完全深复制都实现了内容的复制,但是是否实现对被复制对象的每一层都复制,通过查看多层数组第二层元素的地址来验证:

    NSLog(@"shallow——%p,%p",oldArray[1][0],shallowArray[1][0]);
    NSLog(@"oneDeep——%p,%p",oldArray[1][0],oneDeepLevelArray[1][0]);
    NSLog(@"trueDeep——%p,%p",oldArray[1][0],trueDeepCopyArray[1][0]);

输出结果:

    shallow——0xb000000000000012,0xb000000000000012
    oneDeep——0xb000000000000012,0xb000000000000012
    trueDeep——0xb000000000000012,0xb000000000000013

结论

浅复制地址相同,这点毫无疑问

深复制地址也相同,就说明第二层元素并没有实现内容拷贝,证实iOS中的深复制只实现了单层复制

完全复制地址不同,说明归档解档方法实现的完全复制其每一层都实现内容拷贝

posted @ 2016-10-12 16:24  湘岳  阅读(366)  评论(0编辑  收藏  举报