关于Copy的深度解析

作者: 没有黑眼圈de熊猫 | 来源:发表于2016-10-12 14:46 被阅读165次

    其实也不算深度解析啦,主要是题目要响亮一点大家才有看的欲望嘛!!!

    首先关于Copy想必在面试题中大家见过很多,下面我就写一下我对Copy的理解。

    1.Copy是什么???

    copy和mutableCopy是方法,是NSObject内定义的方法。

    2.Copy有什么用???

    copy顾名思义就是拷贝或者说克隆,所以copy的目的就是复制一份原来的内容,进一步思考为什么需要拷贝?显然:拷贝的目的就是改变原来的内容不影响副本,改变副本也不影响原来的内容。

    3.从NSString,NSMutableString,NSArray,NSMutableArray说明深拷贝和浅拷贝的区别

    首先大家来想一下为什么要用到Copy??Copy的目的所在是什么?为什么需要生成一个新的对象呢???

    Copy是为了互不干扰,生成两个对象是为了相互改变的时候不影响另外一个对象。

    其次大家要牢记一点,使用Copy方法得到的是不可变对象,使用mutableCopy方法得到的必须是可变对象

    一.NSString、NSMutableString非容器对象分析

    1.不可变字符串的copy和mutableCopy

    NSString *str = @"xiaoming";

    NSString *str1 = [str copy];

    NSMutableString * str2 = [str mutableCopy];

    NSLog(@"----str:%p,%@,%@----str1:%p,%@,%@----str2:%p,%@,%@",str,str,NSStringFromClass([str class]),str1,str1,NSStringFromClass([str1 class]),str2,str2,NSStringFromClass([str2 class]));

    打印结果如下:

    ----str:0x10c8e4068,xiaoming,__NSCFConstantString----str1:0x10c8e4068,xiaoming,__NSCFConstantString----str2:0x608000266ac0,xiaoming,__NSCFString

    通过上面的打印结果大家可以看到不可变的字符串经过copy之后没有生成对象,得到的是不可变字符串,经过mutableCopy之后生成了新的对象,得到是可变字符串。

    为什么copy没有得到对象呢???因为原来的对象是不可以修改的,新拷贝的对象也是不可修改的,所以不会影响到另外一个对象。已经符合拷贝的目的 了,所以,OC为了对内存进行优化, 就不会生成一个新的对象。

    为什么mutableCopy会生成新的对象呢?生成的是一个可变对象,这样两个对象其中一个对象改变而不影响另外一个对象。

    2.可变字符串的copy和mutableCopy

    NSMutableString *mulStr = [NSMutableString stringWithFormat:@"abc"];

    NSString *mulStr1 = [mulStr copy];

    NSMutableString * mulStr2 = [mulStr mutableCopy];

    NSLog(@"----str:%p,%@,%@----str1:%p,%@,%@----str2:%p,%@,%@",mulStr,mulStr,NSStringFromClass([mulStr class]),mulStr1,mulStr1,NSStringFromClass([mulStr1 class]),mulStr2,mulStr2,NSStringFromClass([mulStr2 class]));

    打印结果如下:

    ----str:0x600000260180,abc,__NSCFString----str1:0xa000000006362613,abc,NSTaggedPointerString----str2:0x6000002601c0,abc,__NSCFString

    通过上面的打印结果可以看出来可变字符串经过copy和mutableCopy之后都创建了新的对象。经过copy之后得到的是不可变字符串,经过mutableCopy之后 得到的是可变字符串。

    为什么都会生成对象呢???因为可变字符串本来就是可以改变的,为了改变互不干扰,从而生成新的对象,符合拷贝的目的。

    二:NSArray、NSMutableArray容器对象分析

    首先容器对象和非容器对象一样同样遵从下面的总结:

    如果对一不可变对象复制,copy是指针复制(浅拷贝)、mutableCopy就是对象复制(深拷贝)。

    如果是对可变对象复制,都是深拷贝,但是copy返回的对象是不可变的。

    1.NSArray的copy和mutableCopy 

    NSArray *array = [[NSArray alloc]initWithObjects:[NSMutableString stringWithFormat:@"a"],@"b",@"c", nil];

    NSArray *array1 = [array copy];

    NSMutableArray *array2 = [array mutableCopy];

    // NSArray *array3 = [array mutableCopy];

    NSArray *array3 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:array]];

    NSLog(@"----array:%p,----array1:%p,-----array2:%p,----array3:%p",array,array1,array2,array3);

    NSMutableString *str1 = [array objectAtIndex:0];

    [str1 appendString:@"hahhaha"];

    [array2 insertObject:@"111111" atIndex:0];

    NSMutableString *str2 = [array2 objectAtIndex:1];

    [str2 appendString:@"111111"];

    NSLog(@"----array:%@,----array1:%@,-----array2:%@,----array3:%@",array,array1,array2,array3);

    打印结果如下:

     ----array:0x608000242070,----array1:0x608000242070,-----array2:0x608000242b50,----array3:0x608000242d90

     ----array:(

    ahahhaha111111,

    b,

    c

    ),----array1:(

    ahahhaha111111,

    b,

    c

    ),-----array2:(

    111111,

    ahahhaha111111,

    b,

    c

    ),----array3:(

    a,

    b,

    c

    )

    通过上面的打印可以看出来NSArray 经过Copy之后没有创建对象,经过mutableCopy之后创建了新的对象,具体原因和NSString一样,但是里面的元素对象还是指针拷贝,要想做到对象拷贝,可以使用归档的方法。

    2.NSMutableArray 的copy和MutableCopy

    NSMutableArray *mulArray = [[NSMutableArray alloc]initWithObjects:[NSMutableString stringWithFormat:@"abc"],@"def", nil];

    NSMutableArray *mulArray1 = [mulArray copy];

    NSMutableArray *mulArray2 = [mulArray mutableCopy];

    NSLog(@"----array:%p,----arrar1:%p,----array2:%p",mulArray,mulArray1,mulArray2);

    NSMutableString *mulstr = [mulArray objectAtIndex:0];

    [mulstr appendString:@"abc"];

    NSLog(@"----array:%@,-----array1:%@,-----array2:%@",mulArray,mulArray1,mulArray2);

    NSLog(@"----array:%@,-----array1:%@,-----array2:%@",NSStringFromClass([mulArray class]) ,NSStringFromClass([mulArray1 class]),NSStringFromClass([mulArray2 class]));

    打印结果如下:

    ----array:0x60000005af40,----arrar1:0x60000002b1a0,----array2:0x60000005ad60

    ----array:(

    abcabc,

    def

    ),-----array1:(

    abcabc,

    def

    ),-----array2:(

    abcabc,

    def

    )

    通过上面的打印可以看出来NSArray 经过Copy和mutableCopy之后都创建新的对象,具体原因和NSString一样,但是里面的元素对象还是指针拷贝,要想做到对象拷贝,可以使用归档的方法。

    但是大家还要牢记一点:NSMutableArray多次copy每次都会新建对象而NSArray多次copy只新建一次对象。

    4.总结

    正是因为调用copy方法有时候会生成一个新的对象, 有时候不会生成一个新的对象所以:

    如果没有生成新的对象, 我们称之为浅拷贝, 本质就是指针拷贝

    如果生成了新的对象, 我们称之为深拷贝, 本质就是会创建一个新的对象

    最后:最重要的还是记住拷贝的目的,这样理解深浅拷贝都会变得非常简单,改变原来的内容不影响副本,改变副本也不影响原来的内容

    相关文章

      网友评论

      本文标题:关于Copy的深度解析

      本文链接:https://www.haomeiwen.com/subject/oaliyttx.html