![](https://img.haomeiwen.com/i4563271/8b8eab5e4f278c80.png)
对于现在大部分iOS开发者来说,无论是在职的,打算跳槽的,或者还在找工作的,亦或还在培训中,将来可能面临找工作的(现在应该比较少了),面试都无疑是一座摆在面前无法逾越的大山了吧,因为确实很多面试问题,可能我们只是偶尔遇到,或者仅仅知道怎么用,但是却没有进行探究,接下来,我来讲一下,面试过程中几乎必问的 @property 关键字问题~
![](https://img.haomeiwen.com/i4563271/548ce1171a2fc233.png)
对于数组,应该算是我们开发中最常见也是最常用的类型之一了,sunnyxx的这个题目,也确实可以考察出很多面试者的基础知识牢固程度;
如图,我们知道:
·array1 是 NSArray类型的,使用copy是正确的;
·array2 是 NSMutableArray类型的,使用strong 是正确的;
·array3 是 NSMutableArray类型的,使用了copy,可能会导致问题 -->系统认为他是mutable的,可以执行比如addObject 操作,可以写出addObject的方法,但是运行的时候会报错,可以理解为:NSMutable + copy = immutable(不可变);
·array0 的话,NSArray 使用 strong 可能很多人不知道会出现什么问题,甚至很多人可能这么用!其实这么用是有危险的,说的简单一点就是,strong 还是使用原来的内存地址,可能会使得本来的不可变数组变内容发生改变!
探究:NSArray 使用 strong 可能造成的问题!
![](https://img.haomeiwen.com/i4563271/717f3996e63c9765.png)
运行结果如下:
![](https://img.haomeiwen.com/i4563271/f8ad879ccc7033d7.png)
如图:我们发现,strongArray的本质是NSArray,是不可变的,仅在29行发生一次赋值的情况下,最后的结果竟然是变化的!
原理:strong -> 内存地址不变,还是指向本来那块内存,此时指向的是29行的arrayM,arrayM发生改变的时候,由于还是指向这块内存地址,我们的strongArray 虽然是 NSArray,却也跟着arrayM改变了
喜欢在NSArray上使用strong 修饰的朋友看过来了!!
使用copy 修饰 NSArray ,会copy一份新的内存地址,不会出现上述情况!(解决办法:strong 改 copy修饰,over)
![](https://img.haomeiwen.com/i4563271/56cb25bf283dda23.png)
本文要讲的难道就是上面的 NSArray 使用 strong 的问题吗? nonono! 上述问题只是面试中可能遇到的,顺便带一下,本文的主要内容了:mutableCopy 和 copy 的关系;
简单的说,copy -> mutableCopy == NSarray + mutableCopy 约等于 NSMutableArray
But!!关键点来了:你遇到过NSMutableArray 添加对象的时候,失效的问题吗!
探索步骤如下:
第一步:创建一个可变数组,并给他赋值
![](https://img.haomeiwen.com/i4563271/fdd16c565fe39ac2.png)
这里有人会说了,你可变数组怎么这么赋值的,你这里就出错了!
![](https://img.haomeiwen.com/i4563271/0f709c3885fca10b.png)
那这种写法就常见了吧,而且没有⚠️,但是,其实这里这么写和上面的结果是一模一样的,这种大伙儿应该见的用的就多了吧
第二步:往数组中加入新数据
![](https://img.haomeiwen.com/i4563271/b068414817579072.png)
最常见错误出现了!在第一步赋值的时候,其实我们的mutableArray - - myArrayM已经变成不可变的了!所以这里本质是给一个不可变的数组(NSArray 添加对象)肯定报错
第三步:改第二步,使用mutableCopy实现 NSArray ->转 NSMutableArray
![](https://img.haomeiwen.com/i4563271/fcc9c8c0de09cc73.png)
关键问题来了!如图,没有报错,已经可以顺利执行addObject方法了,但是此时才是最可怕的,有执行,却没有加进去!
第四步:将可变的数组_myArrayM当成不可变的来用!
![](https://img.haomeiwen.com/i4563271/4ac47a49964f746c.png)
第5步:全程不给mutableArray赋值,只做add 操作
![](https://img.haomeiwen.com/i4563271/60f93649d16efa7b.png)
结果如下:
![](https://img.haomeiwen.com/i4563271/d9b220157a92fe3f.png)
终于实现了我们想要的效果:全程不对nsmutableArray赋值,仅做add操作!
问题所在:万恶的mutableCopy!
![](https://img.haomeiwen.com/i4563271/4df6e1f9b59ad81f.png)
但凡使用了mutableCopy的!都无法成功添加对象进去!
原理:探究-->mutableCopy:
no1.测试mutableCopy 是否会改变数组的值
![](https://img.haomeiwen.com/i4563271/45ae9bf6af1b351d.png)
如图,如图仅是使用mutableCopy,并不会影响到数组的内容
no2.为mutableCopy赋值
![](https://img.haomeiwen.com/i4563271/1f0a667f7466a9a7.png)
如图:内容发生了改变,但是改变的是arrayM.mutableCopy对象,而不是本身的arrayM对象
no3.查看内存地址查明原因
![](https://img.haomeiwen.com/i4563271/d776a41cd5f53587.png)
原因:我们发现内存地址不一样了!mutableCopy不止对内容进行了copy,还包括了指针,我们发现arrayM的地址,与 进行了 mutableCopy 的testArray的地址是不一样的!!
-->说明他们不是同一个对象了,所以我们在对 arrayM.mutableCopy 进行操作的时候,arrayM并不会受到影响,所以上面的arrayM.mutableCopy - addObject 方法执行完,改变的应该是arrayM.mutableCopy 之后的新对象,arrayM本身是不会受到影响的!
探究Demo:Demo
网友评论
_myArrayM 与 _myArrayM.mutableCopy 是指向不同地址的两个对象(用%p打印验证)
你往_myArrayM.mutableCopy添加元素, _myArrayM能有什么变化