博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS开发之深浅拷贝
阅读量:4146 次
发布时间:2019-05-25

本文共 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进行赋值处理。
这里写图片描述
然后我们打印结果:
这里写图片描述
这样就打印正常了。

你可能感兴趣的文章
idea的安装以及简单使用
查看>>
Windows mysql 安装
查看>>
python循环语句与C语言的区别
查看>>
vue 项目中图片选择路径位置static 或 assets区别
查看>>
vue项目打包后无法运行报错空白页面
查看>>
Vue 解决部署到服务器后或者build之后Element UI图标不显示问题(404错误)
查看>>
element-ui全局自定义主题
查看>>
facebook库runtime.js
查看>>
vue2.* 中 使用socket.io
查看>>
openlayers安装引用
查看>>
js报错显示subString/subStr is not a function
查看>>
高德地图js API实现鼠标悬浮于点标记时弹出信息窗体显示详情,点击点标记放大地图操作
查看>>
初始化VUE项目报错
查看>>
vue项目使用安装sass
查看>>
HTTP和HttpServletRequest 要点
查看>>
在osg场景中使用GLSL语言——一个例子
查看>>
laravel 修改api返回默认的异常处理
查看>>
laravel事务
查看>>
【JavaScript 教程】浏览器—History 对象
查看>>
这才是学习Vite2的正确姿势!
查看>>