copy和mutableCopy都是浅拷贝!!!------你被骗了很多年
所有系统容器类的copy或mutableCopy方法,都是浅拷贝!!!
(ps:什么是容器?比如NSArray,NSMutableArray,NSDictionary,NSMutableDictionary)
很多人一直认为,copy 是浅拷贝,mutableCopy 是深拷贝。我以前也是这么认为的。甚至很多网上的教学视频,很多书籍,很多博客,都是这么说的。但是,这大错特错!
为了防止有人不信,我们先拿出决定性的证据,然后再说其他的。
There are two kinds of object copying: shallow copies and deep copies. The normal copy
is a shallow copy that produces a new collection that
shares ownership of the objects with the original. Deep copies create new objects from the originals and add those to the new collection.
以上三句出自于苹果官方文档 Collections.pdf。
看不懂?没关系。我大致翻译一下。
有两种类型的对象拷贝,浅拷贝和深拷贝。正常的拷贝,生成一个新的容器,但却是和原来的容器共用内部的元素,这叫做浅拷贝。深拷贝不仅生成新的容器,还生成了新的内部元素。
In
the case of these objects, a shallow copy means that a new collection object is created,
but the contents of the original collection are not duplicated—only the object references are copied to the new container.
A deep copy duplicates the compound object as well as the contents of all of its contained objects.
以上两句出自于苹果官方文档 CFMemoryMgmt.pdf。
这个翻译过来和上面的意思几乎一样。
OK,有官方文档为证。现在我们至少可以明确地、大声地说出来:浅拷贝复制容器,深拷贝复制容器及其内部元素。
这点毋庸置疑了吧?
如果你看到这里,那说明你对 “浅拷贝复制容器,深拷贝复制容器及其内部元素“ 这句话没有疑问了。
好,下面我们来验证本文的题目:所有系统容器类的copy或mutableCopy方法,都是浅拷贝!!!。上代码:
- NSMutableArray *element = [NSMutableArray arrayWithObject:@1];
- NSMutableArray *array = [NSMutableArray arrayWithObject:element];
现在我们有一个可变数组,它的名字是 array。
它只有一个元素,叫做 element。
它的这个唯一的元素是一个可变数组。
请在往下看之前确保你理解了上面这三句话。
- NSMutableArray mutableCopyArray = [array mutableCopy];
现在,我们对 array 进行了 mutableCopy,生成了一个新的可变数组,名字叫做 mutableCopyArray。
- [mutableCopyArray[0] addObject:@2];
array 的第一个元素是一个数组对吧。
mutableCopyArray 的第一个元素也是一个数组对吧。
现在我改变了 mutableCopyArray 的元素,往这个元素里加了一个 2。
现在输出 array[0] 看看,结果是 1 和 2。
为什么我们修改了 mutableCopyArray 的元素,结果 array 的元素也跟着改变了呢?
因为二者的元素是共用的。
也就是说,mutableCopy 只复制了容器(此处也就是数组),但是没有复制容器内的元素。
结合官方文档,结论:mutableCopy 是浅拷贝。
不相信?事实摆在眼前,有什么不可相信的?就因为你看的那些视频?那些博客?他们说的就是对的,就不会错了吗?
此外,当你问别人什么是深拷贝什么是浅拷贝的时候,如果他拿 NSString 或者 NSMutableString 给你举例子,那么请你别信,因为他也是在扯淡。
copy
与 mutableCopy 不等同于浅拷贝与深拷贝。
拷贝是针对容器类型和自定义类的,字符串根本就不是容器,还谈什么深拷贝浅拷贝???
说了半天 copy 和 mutableCopy 都是浅拷贝,那到底怎么才是深拷贝?
可以用系统中的
initWithArray:copyItems: 方法,比如:
- NSArray *deepCopyArray = [[NSArray alloc] initWithArray:someArray copyItems:YES];
也可以用我们自定义的方法,比如:
- - (NSArray *)test_deepCopy {
- NSMutableArray *array = [NSMutableArray array];
- for (id element in self) {
- id copyElement = nil;
- if ([element respondsToSelector:@selector(test_deepCopy)]) {
- copyElement = [element test_deepCopy];
- }
- else if ([element respondsToSelector:@selector(copyWithZone:)]) {;
- copyElement = [element copy];
- }
- else {
- copyElement = element;
- }
- [array addObject:copyElement];
- }
- NSArray *result = [NSArray arrayWithArray:array];
- return result;
- }
- - (NSMutableArray *)test_mutableDeepCopy {
- NSMutableArray *array = [NSMutableArray array];
- for (id element in self) {
- id copyElement = nil;
- if ([element respondsToSelector:@selector(test_mutableDeepCopy)]) {
- copyElement = [element test_mutableDeepCopy];
- }
- else if ([element respondsToSelector:@selector(mutableCopyWithZone:)]) {
- copyElement = [element mutableCopy];
- }
- else if ([element respondsToSelector:@selector(copyWithZone:)]) {
- copyElement = [element copy];
- }
- else {
- copyElement = element;
- }
- [array addObject:copyElement];
- }
- return array;
- }
我们来总结一下:
所有系统容器类的copy或mutableCopy方法,都是浅拷贝!!!
浅拷贝复制容器,深拷贝复制容器及其内部元素
copy
与 mutableCopy 不等同于浅拷贝与深拷贝。
拷贝是针对容器类型和自定义类的,字符串根本就不是容器,还谈什么深拷贝浅拷贝???
如果面试官问你什么是深拷贝什么是浅拷贝,请自信地回答他。
如果他不认同你说的,请自信地拿出官方文档给他看。
copy和mutableCopy都是浅拷贝!!!------你被骗了很多年的更多相关文章
- 对copy、mutableCopy理解
Objective - C 中有很多在日常项目中经常用到的常用代码,在这里着重的讲一下关于copy 和 mutableCopy 的区别以及相关用法. Objective - C 中可变对象和不可对象经 ...
- copy 和 MutableCopy
1:copy拷贝得到的对象都是不可变对象,MutableCopy拷贝得到的对象都是可变对象.MutableCopy拷贝得到的对象都是新的对象,会重新分配内存地址,而copy拷贝的对象既可以是新对象,也 ...
- Copy与mutableCopy的个人理解
Copy与mutableCopy的个人理解 1. 相同点 都是将原有对象进行深拷贝(狭义) 这里的狭义上的深拷贝指的是在不考虑编译器在编译时对不可变对象进行copy时采取的优化策略:即将不可变对象的地 ...
- [Objective-C] Copy 和 MutableCopy
看了几篇文章,因为文章很新手向,所以内容很繁琐.故整理一下重点,写了测试程序去了解几个知识点,不讨论基本概念.新博客wossoneri.com传送门 非集合类对象的copy与mutableCopy / ...
- 【转】copy 和 mutablecopy (深拷贝和浅拷贝)
阅读本文之前首先了解copy与retain的区别,如果有不正确的地方望大家多多指教: copy与retain的区别: copy是创建一个新对象,retain是创建一个指针,引用对象计数加1.Copy属 ...
- copy和mutableCopy的深、浅拷贝
对象拷贝主要由两种方式:copy和mutableCopy.浅拷贝是指直接将指针指向原有的地址,从而达到复制的目的.深拷贝是指重新生成一个对象,将原有对象的内容复制到新的对象中.copy 返回的是一个不 ...
- Copy 与MutableCopy的区别
NSString *string = @"origion"; NSString *stringCopy = [string copy]; NSMutableString *stri ...
- iOS Copy 和 MutableCopy的区别 深浅拷贝的区别-供参考
概述 对于系统的非容器类对象,对一不可变对象复制,copy是指针复制(浅拷贝)和mutableCopy就是对象复制(深拷贝).如果是对可变对象复制,都是深拷贝,但是copy返回的对象是不可变的. 对于 ...
- 关于:1.指针与对象;2.深浅拷贝(复制);3.可变与不可变对象;4.copy与mutableCopy的一些理解
最近对深浅拷贝(复制)做了一些研究,在此将自己的理解写下来,希望对大家有所帮助.本人尚处在摸索阶段,希望各位予以指正. 本文包括如下方向的探索: 1.指针与对象: 2.深/浅拷贝(复制): 3.可变/ ...
随机推荐
- mysql导出指定字段或指定数据到文件中
使用mysqldump把mysql数据库的数据导出到文件中还是挺方便的:比如说要导出baijunyao数据库: // mysqldump -u用户名 -p 数据库名 [表名]> 导出的文件名 m ...
- java_AWT常用组件
Button:按钮,可接受单击操作. Canvas:用于绘图的画布. Checkbox:复选框组件(也可以变成单选框组件). CheckboxGroup:用于将多个Checkbox组件合成一组,一组C ...
- c++ STL 容器——序列
STL中11个容器类型分别是deque,list,queue,priority_queue,stack,vector,map,multimap,set,multiset,bieset(在比特级处理数据 ...
- akoj-1267-独木舟上的荡漾
独木舟上的荡漾 Time Limit:1000MS Memory Limit:65536K Total Submit:76 Accepted:44 Description 进行一次独木舟的旅行活动, ...
- Exception in thread "main" java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
这个问题当然是找不到mysql的驱动类,可能是环境CLASSPATH有问题或者就是那个人没有加载jdbc的驱动.我在网上下载mysql-connector-java-5.0.8-bin.jar一个这个 ...
- JavaScript中的EcMAScript学习笔记
一.Javascript概述(知道) a.一种基于对象和事件驱动的脚本语言 b.作用: 给页面添加动态效果 c.历史: 原名叫做livescript.W3c组织开发的标准叫ECMAs ...
- [Usaco2007 Open]Fliptile 翻格子游戏 状态压缩
考试想到了状压,苦于T1废掉太长时间,于是默默输出impossible.. 我们知道,一个格子的翻转受其翻转次数和它相邻翻转次数的影响. 由每一个位置操作两次相当于把它翻过来又翻回去,所以答案中每一个 ...
- [bzoj 2438][中山市选2011]杀人游戏 概率+tarjan
考试的时候想了很多,不知道它那个概率究竟是怎么算..没想到能蒙30分.rp爆发hhh 题解转自不知道哪里来的老师发的(代码出自自己). 实际上警察就是两种结果——查到犯人或死亡,而死亡事件一定是包含在 ...
- Oracle execute and call
--execute和call的区别 -------------------------2014/01/14 EXEC is a sqlplus command that put its argumen ...
- include包含头文件的语句中,双引号和尖括号的区别
include包含头文件的语句中,双引号和尖括号的区别 #include <>格式:引用标准库头文件,编译器从标准库目录开始搜索 #incluce ""格式:引用非 ...