浅拷贝&深拷贝之回顾

拷贝 在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,这样,才可以进行后面的更改。

你可能感兴趣的:(浅拷贝&深拷贝之回顾)