美文网首页
浅拷贝&深拷贝之回顾

浅拷贝&深拷贝之回顾

作者: Rachel_雷蕾 | 来源:发表于2020-11-17 18:38 被阅读0次

    拷贝 在iOS开发中太习以为常了,我们都非常了解了,本篇就再次回顾这个老生常谈的知识点

    一、定义

    浅拷贝:拷贝指针,仅拷贝指针地址,对象的内存区域还是一样的,即新的指针也指向同一片内存。
    深拷贝:拷贝内存。即真正的复制了一份,指针地址,内存地址都完全不一样。

    那么iOS中是怎么实现深、浅拷贝的?

    二、Copy和mutableCopy

    是通过CopymutableCopy来实现的拷贝的
    我们知道,若想令自己所写的对象具有拷贝功能,则需实现 NSCopying协议,如果可变的话,如果定义的对象分为可变版本与不可变版本,那么就要同时实现 NSCopying 与 NSMutableCopying协议。
    系统的NSStringNSArrayNSDictionary就是满足了NSCopying和协议NSMutableCopying 协议的类,
    下面我们就以NSStringNSArray分别代表非集合类和集合类为例

    非集合类
    NSString

    • 定义一个NSString变量str1,分别copy和mutableCopy,打印内存地址


      image.png

      copy后,地址没有变化,mutableCopy后,地址变化了

    • 定义一个NSMutableString变量str1,重复上述操作,打印地址


      image.png

      copy和mutableCopy后,地址都变化了

    结论:😄
    对 immutable 对象进行 copy 操作,是指针复制,mutableCopy 操作时内容复制;对 mutable 对象进行 copy 和 mutableCopy 都是内容复制

    [immutableObject copy] // 浅复制
    [immutableObject mutableCopy] //深复制
    [mutableObject copy] //深复制
    [mutableObject mutableCopy] //深复制

    集合类
    NSArray

    • 定义一个NSArray对象ar1,分别copy和mutableCopy,打印


      image.png

      copy后地址没变,mutableCopy后地址改变
      那么它内部的元素会变化么?我们更改其中第一个元素,看是否都更改了


      image.png

    ar1更改可第一个元素,ar2和ar3也同步更新了,说明内部元素只是浅拷贝

    • 定义一个NSMutableArray对象ar1,分别copy和mutableCopy,打印


      image.png

      三个地址完全不同,都是地址拷贝;同时我们更改了ar1的第一个元素,其他数组也同样更新了,也是指针拷贝

    结论😄:对 immutable 对象进行 copy,是指针复制, mutableCopy 是内容复制;对 mutable 对象进行 copy 和 mutableCopy 都是内容复制。但是:集合对象的内容复制仅限于对象本身,对象元素仍然是指针复制

    [immutableObject copy] // 浅复制
    [immutableObject mutableCopy] //单层深复制
    [mutableObject copy] //单层深复制
    [mutableObject mutableCopy] //单层深复制

    到此为止,那我们属性修饰符里用copy、mutableCopy还是strong呢?

    三、property修饰符
    • 因为父类指针可以指向子类对象,使用 copy 的目的是为了让本对象的属性不受外界影响,使用 copy 无论给我传入是一个可变对象还是不可对象,我本身持有的就是一个不可变的副本.
    • 如果我们使用是 strong ,那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性

    copy 此特质所表达的所属关系与 strong 类似。然而设置方法并不保留新值,而是将其“拷贝” (copy)。 当属性类型为 NSString 时,经常用此特质来保护其封装性,因为传递给设置方法的新值有可能指向一个 NSMutableString 类的实例。这个类是 NSString 的子类,表示一种可修改其值的字符串,此时若是不拷贝字符串,那么设置完属性之后,字符串的值就可能会在对象不知情的情况下遭人更改。所以,这时就要拷贝一份“不可变” (immutable)的字符串,确保对象中的字符串值不会无意间变动。只要实现属性所用的对象是“可变的” (mutable),就应该在设置新属性值时拷贝一份。

    所以
    修饰NSString或者NSArray、NSDictionary时,一般使用copy,可以防止setter方法时,使用的是子类(可变对象)赋值,后面更改时,导致数据混乱。
    修饰NSMutableString或者NSMutableArray、NSMutableDictionary时,使用strong,这样,才可以进行后面的更改。

    相关文章

      网友评论

          本文标题:浅拷贝&深拷贝之回顾

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