首页 > 代码库 > 黑马程序员--浅析浅复制和深复制的本质

黑马程序员--浅析浅复制和深复制的本质

<style type="text/css" isprelink="true">@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);</style><style type="text/css">@import url(/css/cuteeditor.css);</style>

 

 实例浅析oc中的浅复制和深复制的本质



代码段1:



#import <Foundation/Foundation.h>


int main(int argc, const char * argv[]) {

    @autoreleasepool {

        

        

        NSMutableArray *dataArray = [NSMutableArray arrayWithObjects:@"one",@"two",@"three",@"four", nil];

        NSMutableArray *dataArray2;

        

        // copy

        

        dataArray2 = dataArray;

        [dataArray2 removeObjectAtIndex:0];

        

        NSLog(@"dataArray:");

        

        for (NSString *elem in dataArray) {

            NSLog(@"%@",elem);

        }

        

        NSLog(@"dataArray2: ");

        

        for (NSString *elem in dataArray2) {

            NSLog(@"%@",elem);

        }

        

        // mutableCopy

        

        dataArray2 = [dataArray mutableCopy];

        [dataArray2 removeObjectAtIndex:0];

        

        NSLog(@"dataArray:");

        

        for (NSString *elem in dataArray) {

            NSLog(@"%@",elem);

        }

        

        NSLog(@"dataArray2: ");

        

        for (NSString *elem in dataArray2) {

            NSLog(@"%@",elem);

        }

        

    }

    return 0;

}


 打印结果如下:

dataArray:

 two

 three

 four

 dataArray2: 

 two

 three

 four

 dataArray:

 two

 three

 four

 dataArray2: 

 three

 four



代码段2:

#import <Foundation/Foundation.h>


int main(int argc, const char * argv[]) {

    @autoreleasepool {

        

        

        NSMutableArray *dataArray = [NSMutableArray arrayWithObjects:

                                     [NSMutableString stringWithString:@"1"],

                                     [NSMutableString stringWithString:@"2"],

                                     [NSMutableString stringWithString:@"3"],

                                     [NSMutableString stringWithString:@"4"],

                                     [NSMutableString stringWithString:@"5"],

                                     [NSMutableString stringWithString:@"6"],

                                     [NSMutableString stringWithString:@"7"],

                                      nil];

        

        NSMutableArray *dataArray2;

        

        NSMutableString *mStr;

        

        NSLog(@"dataArray :");

        

        for (NSString *elem in dataArray) {

            NSLog(@"%@",elem);

        }

        

        

        // 做一次拷贝,然后改变第一个字符串

        

        dataArray2 = [dataArray mutableCopy];

        

        mStr = [dataArray objectAtIndex:0];

        

        [mStr appendString:@"oc"];

        

        NSLog(@"dataArray :");

        

        for (NSString *elem in dataArray) {

            NSLog(@"%@",elem);

        }


        NSLog(@"dataArray2 :");

        

        for (NSString *elem in dataArray2) {

            NSLog(@"%@",elem);

        }


        

        

    }

    return 0;

}



打印结果如下:

dataArray :

1

2

3

4

5

6

7

dataArray :

1oc

2

3

4

5

6

7

dataArray2 :

1oc

2

3

4

5

6

7



为了便于理解,我们可以把数组对象看成指针数组,dataArray这个指针是指向指针数组的指针,数组中的元素指针指向的是对象



分析:copy复制对象结果是dataArray和dataArray2指向同一个数组对象。

MutableCopy复制对象的结果是,创建数组对象的副本,即dataArray 和 dataArray2指向不同的对象,但是两个数组对象中的元素对应的指向的同一个对象  即dataArray[0] 和 dataArray[0]指向同一个对象,dataArray[1] 和 dataArray2[1]指向同一个对象


从内存的管理的角度去分析

copy的结果是数组对象的计数器加1,mutableCopy的结果是数组对象中的元素(对象)的计数器加1


代码段1:分析

copy只是复制数据对象的引用,数组对象本身发生改变,不管用哪个指针去访问,结果都相同


MutableCopy复制元素的引用,因为两个数据对象指针并没有指向同一个数组对象,所以dataArray2数组元素的个数改变并不影响dataArray


dataArray的元素依旧有指针指向@“two”这个字符串对象



代码段2:分析


mutableCopy创建了数据对象的副本,并把副本的地址传递给dataArray2。数组对象的元素对象计数器都加1。当我们改变了数组元素对象的内容的时候,由于两个数组对象的元素指针指向相同的对象,所以两个数组对象打印结果会相同



想要做到完全复制,我们就要一层一层的胃对象创建副本,知道最底层,这个怎么理解呢,就拿上面两段代码来说copy没有创建副本,mutableCopy创建了一层,我们只要再为数组对象元素,为这些字符串对象都创建副本,那我我们再怎么去改动dataArray 也不会影响到dataArray2



我们可以使用Foundation的归档能力创建对象的深复制。如下代码所示,dataArray归档到一个缓冲区,然后再把它解归档,将结果指派给dataArray2,从而将dataArray复制给dataArray。这个过程不需要使用文件。归档和解归档过程都可以在内存中发生。代码如下



#import <Foundation/Foundation.h>


int main(int argc, const char * argv[]) {

    @autoreleasepool {

        NSData *data;

        NSMutableArray *dataArray = [NSMutableArray arrayWithObjects:

                                     [NSMutableString stringWithString:@"1"],

                                     [NSMutableString stringWithString:@"2"],

                                     [NSMutableString stringWithString:@"3"],

                                     [NSMutableString stringWithString:@"4"],

                                     [NSMutableString stringWithString:@"5"],

                                     [NSMutableString stringWithString:@"6"],

                                     [NSMutableString stringWithString:@"7"],

                                     nil];

        

        NSMutableArray *dataArray2;

        NSMutableString *mStr;

        

        // archiver进行深复制

        

        data = http://www.mamicode.com/[NSKeyedArchiver archivedDataWithRootObject:dataArray];

        dataArray2 = [NSKeyedUnarchiver unarchiveObjectWithData:data];

        

        mStr = [dataArray2 objectAtIndex:1];

        [mStr appendString:@"ios"];

        

        NSLog(@"dataArray :");

        

        for (id obj in dataArray) {

            NSLog(@"%@",obj);

        }

        

        NSLog(@"dataArray2 :");

        

        for (id obj in dataArray2) {

            NSLog(@"%@",obj);

        }


        

    }

    return 0;

}



dataArray :

1

2

3

4

5

6

7

dataArray2 :

1

2ios

3

4

5

6

7


<style type="text/css" isprelink="true">@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);</style><style type="text/css">@import url(/css/cuteeditor.css);</style>

黑马程序员--浅析浅复制和深复制的本质