iOS面试篇--浅拷贝和深拷贝和copy关键字

前言

iOS面试中最经常碰到的就是内存方面的问题,比如面试官问你浅拷贝和深拷贝的区别,copy和stong关键字的区别,weak和assign的区别,以及衍生下去容器的拷贝以及元素如何深拷贝,等等。

正文

一、关于浅拷贝和深拷贝

让我们来做一组实验:1,非容器不可变对象的copy和mutablecopy

iOS面试篇--浅拷贝和深拷贝和copy关键字_第1张图片
图1

打印结果:

图2

zifuchuan和copystr的地址都是0x10070b0e0说明对zifuchuan的copy操作是指针拷贝,mutstr的地址是0x10070acd0,说明对zifuchuan的mutablecopy操作是内容拷贝。

2,非容器可变对象的copy和mutablecopy

iOS面试篇--浅拷贝和深拷贝和copy关键字_第2张图片
图3

打印结果:

图4

其中mutablestr,copymutablesr,mutmutablestr的地址各不一样,说明对可变字符串的copy和mutableCopy操作都是内容拷贝,mutalbeCopy拷贝的是可变字符串。

3,容器可变对象的copy和mutablecopy

iOS面试篇--浅拷贝和深拷贝和copy关键字_第3张图片
图5

打印结果:

图6

copyarray的地址和array一样都是0x100708390说明不可变数组的copy操作是指针拷贝,mutcopyarray的地址是0x10070a9b0和array不一样,说明对不可变数组的mutableCopy操作是内容拷贝,我们看一下array,copyarray,mutcopyarray三个数组的元素地址,都一样没有变说明容器可变数组的元素是指针拷贝。

4,容器可变对象的copy和mutablecopy

iOS面试篇--浅拷贝和深拷贝和copy关键字_第4张图片
图7

打印结果:

图8

mutarray,copymutarray,mutcopymutarray三个对象的地址分别为0x1007092a0,0x100709430,0x100709450,说明对可变数组的copy和mutableCopy操作都是深拷贝,其中copy的对象是不可变的,mutableCopy的对象是可变的。我们在看一下三个数组的元素地址,都是一样,说明对可变数组的元素拷贝也是指针拷贝

二、@property的copy关键字

关于copy关键字,用的较多的数据类型是NSString和block,但是有一种数据类型可变对象,若使用copy则很容易出错,如NSMutableArray,NSMutableString。

iOS面试篇--浅拷贝和深拷贝和copy关键字_第5张图片
图9

对类的属性testMutArray和testMutstring直接赋值,此时testMutArray和testMutstring属性已经变为不可变对象,因为copy关键字使内存中的可变对象copy一份新的不可变对象。如图9,把23和29行注释去掉后运行工程后直接crash,因为self.testMutArray变量已经是一个不可变数组,self.testMutstring是一个不可变字符串。

三、数组元素的深拷贝

我们知道数组的拷贝中无论是可变数组还是不可变数组,其元素拷贝都是指针拷贝,那么有没有方法可以让它深拷贝呢。

1,有一种方法,创建新数组,遍历数组中的元素,copy后加入新数组。

iOS面试篇--浅拷贝和深拷贝和copy关键字_第6张图片
图10

其中Person类需要实现NSCopying的协议方法- (id)copyWithZone:(NSZone*)zone,要不然对象无法拷贝。

iOS面试篇--浅拷贝和深拷贝和copy关键字_第7张图片
图11

2,还有一种方法是创建数组是使用[[NSMutableArray alloc] initWithArray:arr copyItems:YES] 方法,前提是数组中的元素若是对象也必须实现NSCopying或NSMutableCopying协议方法。

iOS面试篇--浅拷贝和深拷贝和copy关键字_第8张图片
图12

如图12,23行和27行打印出来的元素对象地址是不一样的:

图13

说明元素已经深拷贝了。好了,本篇介绍就到这里。

你可能感兴趣的:(iOS面试篇--浅拷贝和深拷贝和copy关键字)