本文共 1536 字,大约阅读时间需要 5 分钟。
序言:
在学习iOS之深浅拷贝的时候,一定要明白OC的内存分布。下面以一个字符串为例:
我们可以看到temp1和temp2的地址是一样的。
我们再看看下面这一个例子:
当使用copy时,打印出str和copyString两者的地址是一样的。而mutabelCopyString的地址和前两者不一样,这就涉及到了深拷贝和潜拷贝。
一、Copy和mutableCopy的介绍
点击跳转详细讲解
我们先看看下面的这个表格:
在理解copy和mutableCopy之前你首先要明白下面的打印代表什么意思:
对于打印的四个结果我们要知道什么意思,stirngContentAddress打印的是字符串@“123”在栈区的地址,AfterChangeStirngContentAddress 表示字符串改变成@“456”后在栈区的地址,两者前后肯定是不一样的,而stirngPointAddress 则代表你所定义的指针string的地址,改变字符串你只是改变了string指针的指向,而它本身的地址是不变的。1、NSString的copy/mutableCopy
string和copyString的地址一样,但mutableString的却不一样。2、MutableString的copy/mutableCopy
stirng和copyString、mutableString三者的地址都不一样3、理解深复制(mutableCopy)
1)我们来看看第一种写法: 我们发现我们改变原数组dataArray2,也会影响深复制后的dataArray3,深复制到底是怎么回事呢?代码dataArray3=[dataArray2 mutableCopy];只是对数组dataArray2本身进行了内容拷贝,但是里面的字符串对象却没有进行内容拷贝,而是进行的浅复制,那么dataArray2和dataArray3里面的对象是共享同一份的。所以才会出现上面的情况。2)我们看看这一种写法:
我们发现dataArray2不再受dataArray3的影响了,但是这种复制仍然又问题。3)我们来看看这一种写法:
很容易发现dataArray2受dataArray3的影响,这是因为dataArray3=[[NSMutableArray alloc]initWithArray:dataArray2 copyItems:YES];仅仅能进行一层深复制,对于第二层或者更多层的就无效了。4)我们看看最终写法:
我们可以看到这里dataArray2不再受dataArray3的影响了。结论:要想对多层集合对象进行复制,我们需要进行完全复制,这里可以使用归档和解档。 4)类(NSObject)的拷贝 这里我们建立一个Person类: 在.h中我们为Person类定一个年龄.m中建立一个Person类对象,给年龄赋值
然后运行一下:
出现打印崩溃现象,错误信息是-[Person copyWithZone:]: unrecognized selector sent to instance 0x6080000122e0 是因为copy时没有找到person对象,这里提到了一个方法copyWithZone,接着我们实现在Person类的.m中copyWithZone方法 接着我们打印copy的perons对象 直接打印出我们在.m中返回的字符串了。 如果在这里我们打印copy出来的对象的年龄 看看会出现什么结果: 这里程序崩溃,查看错误日志是因为没有找到age属性,所以需要我么你在copyWithZone中对Person对象age进行赋值处理。 然后我们打印结果: 这样就打印正常了。