【iOS开发每日小笔记(五)】实测copy到底是个神马玩意
这篇文章是我的【iOS开发每日小笔记】系列中的一片,记录的是今天在开发工作中遇到的,可以用很短的文章或很小的demo演示解释出来的小心得小技巧。它们可能会给用户体验、代码效率得到一些提升,或是之前自己没有接触过的技术,很开心的学到了,放在这里得瑟一下。90%的作用是帮助自己回顾、记忆、复习。
上个月月底我写了一篇博文http://www.cnblogs.com/pigpigDD/p/3880866.html 总结了我理解的ARC,strong、weak的一些用法。今天花了一点时间研究了一下copy这个属性。
网上看了很多博客,大家都在讨论的是copy的工作原理,“几种变量(容器非容器、可变非可变)的两种copy(copy、mutableCopy)”到底会返回什么变量。如:
http://www.cnblogs.com/ludashi/p/3894151.html
http://www.gowhich.com/blog/472
http://blog.segmentfault.com/channe/1190000000604331?page=1#c-1190000000604331-1050000000607780
当然他们写的都很卖力,用了一大堆demo代码来说明问题,也分析了自定义类怎么实现NSCopying copyWithZone等等都很全面。但是我的这篇文章想借题发挥分享四点我的想法:
一:几篇博文中存在一些不合理的地方,比如用NSString常量来测retainCount值(MRC模式),NSString常量(NSString *string = @"XX"),包括[NSString stringWithString:]以及 [[NSString alloc] initWithString:]这几个返回的都是NSString常量,是保存在内存的“文字常量区”的,不同于用户使用绝大多数alloc init或绝大多数类方法初始化创建的对象,那些对象是创建在堆上的。因此对前者做retainCount是相对没有意义的,你得到的是“-1”;还有一些文章中,对返回值到底是可变还是不可变写的很随意,这也是对网友的误导。
二,很少有文章能说明,什么时候用copy或mutableCopy,为什么要用他们。那么在我看来,1,假如你想用对象A的值创建一个新的不可变对象B,那么请你用copy来修饰B,也就是B = [A copy];2,如果你想用对象C的值创建一个新的可变对象D,那么请你用mutableCopy来修饰D,也就是D = [C mutableCopy];
总结一下:
①:考虑返回结果是否是可变对象:A和C是无所谓可变还是不可变的,而是通过copy/mutableCopy来控制;
②:当修饰词为copy时,考虑返回结果是单纯的引用(内存地址相同)还是全新的创建:A/C如果是可变对象,则为新创建,反之则为引用;
③:当修饰词为mutableCopy时,返回结果都是用原对象的值重新创建的新对象。
三:我也写了一个自己的demo用来言简意赅的探索copy、mutableCopy到底是“神马玩意”,在这里:https://github.com/pigpigdaddy/CopyMutableCopyDemo 读者可通过解注释,来测试。
四:对于自定义类怎么实现NSCopying copyWithZone 以及 如何进行严格意义上的完全深拷贝(数组内的值完全深拷贝),不是本文的讨论内容,请参考:http://www.cnblogs.com/scorpiozj/archive/2011/01/25/1944496.html 。