关于oc深浅拷贝问题可能做过ios开发的都有了解到,尤其是面试特别喜欢问深浅拷贝的问题.但大多有点误区,即便是有几年开发经验的ios程序员来说,很少有人说到伪拷贝这个概念,而只分深浅拷贝,新开了内存就说深拷贝,只拷贝的引用就说浅拷贝,这其实是片面的理解,在这里我们一起来探究一下拷贝究竟怎么区分.

       首先创建一个工程,新建一个Person类,给Person类写一个name属性,我们让Person类拥有可拷贝的特性,首先签订NSCoping协议,然后实现copyWithZone方法.代码如下:

wKiom1aQo9ahI3hlAAEEtPF_MCc774.png

   1.伪拷贝--拷贝地址,相当于retain操作,造成对象引用计数+1

   在copyWithZone中代码如下


wKioL1aQpLejJDOxAAC61EWyJmk479.png然后我们在main.m文件中创建Person对象并且拷贝一个对象出来,分别打印其地址以及name属性地址,以p1,p2的引用计数.

wKioL1aQphCD6bGbAAI7xNmN6to168.png

可以发现p1,p2地址相同,两个name地址也相同,而引用计数为2.可见这种拷贝仅仅拷贝了一个引用然后对对象的引用计数+1,跟retain并无分别.


2.浅拷贝--对象开辟新的空间,但是对象的实例变量指向同一块空间

copyWithZone方法中代码如下:

wKiom1aQpuiitlwsAAE9PdugELU432.png

运行程序,继续查看打印的地址和引用计数发现,p1,p2地址不同说明新开辟了空间,p1.name,p2.name地址不同说明两个对象name这个实例变量指向的还是同一块内存,p1,p2引用计数分别为1.就不难解释浅拷贝开辟新的空间,但是对象的实例变量指向同一块空间这句话了.


3,深拷贝--对象开辟新的空间,两个对象的实例变量也指向不同的空间。

copyWithZone方法中代码如下:

wKioL1aQqEDAqjZUAAFgtm3tauc947.png

运行程序查看打印的地址信息发现,p1,p2地址不同,p1.name,p2.name地址不同,p1,p2引用计数都为1,说明现在p1,p2再没有一点瓜葛,完全是在内存中独立存在,也就是开辟新的空间,并且实例变量也指向不用的空间,这才是真正意义上的深拷贝.


PS:

利用周六匆匆写的,望多多指正,欢迎转载,转载时请注明出处.谢谢~