iOS - Copy 与 MutableCopy

作者: Mitchell | 来源:发表于2015-08-04 11:10 被阅读5087次

参考链接


一、深拷贝和浅拷贝####

  • 深拷贝:对象拷贝 - 直接拷贝内容。
  • 单层深拷贝:这种方式只能够提供一层内存拷贝(one-level-deep copy),并非真正的深拷贝。
  • 浅拷贝:指针拷贝 - 将指针中的地址值拷贝一份。

二、对于非集合对象 Copy 与 mutableCopy 的实践#####
  • 思路:我用四个方案来验证 Copy 与 mutableCopy 的区别。
  • 方案:
    • 方案一:copy不可变的字符串
NSString*str = @"aaa";
NSString*copyStr = [str copy];
NSLog(@"str = %p copyStr= %p",str,copyStr);
NSLog(@"指针地址:str = %p copyStr= %p",&str,&copyStr);

输出结果:str = 0x104d94068 copyStr= 0x104d94068
指针地址:str = 0x7fff529e9aa8 copyStr= 0x7fff529e9aa0
小结:对不可变的字符串的copy,我们对象的内存地址没有改变,只是指针的地址改变了,所以在这里我们默认进行了一次浅拷贝,只拷贝了指针。

- 方案二:`copy可变的字符串`
NSMutableString*str1 = [NSMutableString stringWithFormat:@"bbb"];
NSString*copyStr1 = [str1 copy];
NSLog(@"str1 = %p copyStr1 = %p",str1,copyStr1);
NSLog(@"str1 = %p copyStr1= %p",&str1,&copyStr1);

输出结果:str1 = 0x7fa522712cd0 copyStr1 = 0x7fa522717ba0
指针地址:str1 = 0x7fff529e9a98 copyStr1= 0x7fff529e9a90
小结:对可变字符串的copy,我们默认进行了一次深拷贝,直接拷贝了对象。
- 方案三:mutableCopy不可变字符串的

NSString*str2 = @"ccc";
NSMutableString *copyStr2 = [str2 mutableCopy];
NSLog(@"str2 = %p copyStr2 = %p",str2,copyStr2);

输出结果:str2 = 0x10d216108 copyStr2 = 0x7fa522726290
小结:对于不可变字符串的mutableCopy我们默认进行了深拷贝。
- 方案四:mutableCopy可变字符串

NSMutableString*str3 = [NSMutableString stringWithFormat:@"ddd"];
NSMutableString*copyStr3 = [str3 mutableCopy];
NSLog(@"str3 = %p copyStr3 = %p",str3,copyStr3);

输出结果:str3 = 0x7fa5227153c0 copyStr3 = 0x7fa5227263f0
小结:对于可变字符串的mutableCopy我们默认进行了深拷贝。


三、对于集合对象采用 Copy 和 MutableCopy 的实践

  • 对集合对象采用 Copy 和 mutableCopy 来进行实践
NSArray * arr = @[@"1",@"2",@"3"];
NSMutableArray * mutableArr = [arr mutableCopy];
NSArray * copyArr = [arr copy];
NSMutableArray * newArr = [NSMutableArray arrayWithObjects:@"3",@"2",@"1", nil];
NSArray * newCopyArr = [newArr copy];
NSMutableArray * newMutableCopyArr = [newArr mutableCopy];
//测试 arr 的 copy 和 mutableCopy
NSString * str = [arr firstObject];
NSString * copyStr = [copyArr firstObject];
NSString * mutableStr = [mutableArr firstObject];
//测试 mutableArr 的 copy 和 mutableCopy
NSString * str = [newArr firstObject];
NSString * newCopyStr = [newCopyArr firstObject];
NSString * newMutableCopyStr = [newMutableCopyArr firstObject];
图3-1.png
图 3-2.png
图3-3.png
  • 通过图 3-1 可以见到,对于不可变的 arr 如果进行 copy 的话会进行浅拷贝,如果 mutableCopy 会进行内容拷贝。但是,通过图 3-2 打印出的地址信息,这里的内容拷贝仅仅是拷贝 array 这个对象,array 集合内的元素仍然是指针拷贝。所以可以定义为是单层深拷贝。
  • 通过图 3-3 可以看出,对于可变的集合元素的 copy 与 mutableCopy 都是单层深复制。

四、结论####

  • 对于非集合对象
    • copy:因为copy默认返回的是不可变的,所以当我们对一个不可变的字符串进行copy的时候,我们只是拷贝了它的指针(浅拷贝)。当我们对一个可变的字符串进行拷贝的时候,因为类型转变了,我们需对其进行深拷贝
    • mutableCopy:默认返回的是一个可变的对象,适用于可变的对象,例如NSMutableString,NSMutableArray,NSMutableDictionary、etc。 无论对于可变的字符串还是不可变的字符串进行mutableCopy,系统都默认进行深拷贝,那么为什么对于相同类型的进行mutableCopy返回的仍然是新的对象呢,因为在这里系统要保证,旧的对象和新的对象都是可变的,切他们之前不会相互影响。
  • 对于集合对象
    • 对于不可变的集合对象,copy 是浅拷贝,mutableCopy 是单层深拷贝。
    • 对于可变的集合对象,无论 copy 或者 mutableCopy 都是单层深拷贝。

相关文章

  • iOS开发深拷贝与浅拷贝的关系

    IOS开发之深拷贝与浅拷贝(mutableCopy与Copy)详解 copy与retain的区别: copy是创建...

  • iOS开发之copy

    iOS中copy有两种copy和mutableCopy

  • copy与mutablecopy使用对比

    杂七杂八 copy和mutableCopy都是浅拷贝!!!iOS中的copy,mutableCopy,深拷贝和浅拷...

  • Objective-C中的浅拷贝和深拷贝

    Objective-C中的浅拷贝和深拷贝IOS开发之深拷贝与浅拷贝(mutableCopy与Copy)详解iOS ...

  • iOS:浅谈 深.浅拷贝与copy.strong

    概要的测试了copy与mutableCopy的区别 深.浅拷贝●copy/mutableCopy NSString...

  • iOS copy与mutableCopy

    以前只知道copy操作过的对象,会得出一个新的不可变对象而mutableCopy操作过的对象,会得出一个新的可变对...

  • iOS - copy与mutableCopy

    浅拷贝与深拷贝 浅拷贝:指针拷贝,不产生新的对象,源对象的引用计数器+1 深拷贝:对象拷贝,会产生新的对象,源对象...

  • iOS - copy 与 mutableCopy

    一说到拷贝,就不得不提浅拷贝和深拷贝。 何谓浅拷贝?何谓深拷贝? 往简单的说: 浅拷贝:拷贝地址。 深拷贝:拷贝内...

  • iOS Copy 与 MutableCopy

    用不可变容器类创建的对象 进行的copy 是指针复制,没有创建对象,进行的mutableCopy不再是地址拷贝,是...

  • iOS - Copy 与 MutableCopy

    参考链接 一、深拷贝和浅拷贝#### 深拷贝:对象拷贝 - 直接拷贝内容。 单层深拷贝:这种方式只能够提供一层内存...

网友评论

  • Hanser0503:Mark,写的很好!!学习了
  • 孤独的演奏家:不可变对象 调copy 与 直接赋值 obj1 = targetObj;
    又有什么区别呢..
  • 白雪天枫:最后总结语挺好的
  • 洛阳如是:对于可变的集合对象,无论 copy 或者 mutableCopy 都是单层深拷贝。
    这句话有错误, 如果是可变的数组 copy后 里面的对象地址是不变的,而mutableCopy后对象地址才会发生改变
    Mitchell:@洛阳如是 建议看一下对单层深拷贝与深拷贝的区别。如果自己试验了,也可以截图发来一起讨论一下。我看了一下网上的结论也和我这边一致。
    洛阳如是:@Mitchell 肯定了 数组里放的对象 要深copy这个数组最好用mutableCopy
    Mitchell:你试验了额?:flushed:
  • 三十一_iOS:这是我看过讲的最清楚的文章,大赞作者
  • 058ff34b7220:感谢分享,有帮助。
  • 3a601209eff1:学习了,马上自己实践一下
  • 崠崠: 帮助了

本文标题:iOS - Copy 与 MutableCopy

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