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


    ------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

     

     实例浅析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 = [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


  • 相关阅读:
    我总结的面试题系列:kafka
    RabbitMQ大厂面试题
    [Algorithm] 并查集
    [LintCode] 编辑距离
    [LeetCode] Length of Longest Fibonacci Subsequence
    [LintCode] 交叉字符串
    [LeetCode] Permutation Sequence
    Permutation Sequence
    [LeetCode] Next Permutation
    [LeetCode] Longest Palindromic Substring
  • 原文地址:https://www.cnblogs.com/frozen1224/p/4245516.html
Copyright © 2020-2023  润新知