iOS中的深复制与浅复制
很多语言中都有深复制浅复制的概念,如C++,ObjC等。简单来说,浅复制就是两个变量指向了同一块内存区域,深复制就是两个变量指向了不同的内存区域,但是两个内存区域里面的内容是一样的。
浅复制示意图:

深复制示意图:

iOS开发中,浅复制和深复制要更复杂一些,涉及到集合对象和非集合对象的copy与mutableCopy。
非集合对象:如NSString,NSInteger,NSNumber……
集合对象:如NSArray,NSDictionary,……
1:非集合对象的copy与mutableCopy。
非集合对象的copy与mutableCopy,只需要遵循以下规则即可:
(1)可变对象的copy和mutableCopy方法都是深复制
(2)不可变对象的copy方法是浅复制,mutableCopy方法是深复制
(3)copy方法返回的对象是不可变对象
下面通过代码来验证:
可变对象的copy与 mutableCopy方法:
void testMutable()
{
//可变对象的复制,copy和mutableCopy都是深拷贝
NSMutableString *str1 = [NSMutableString stringWithString:@"test"];
NSMutableString *str2 = [str1 copy];
//copy返回的是不可变对象,因此str2不能改变,会发生崩溃
//[str2 appendString:@"test"];
NSMutableString *str3 = [str1 mutableCopy];
[str3 appendString:@"test"];
NSLog(@"%@ %@ %@",str1,str2,str3);
NSLog(@"%p %p %p",str1,str2,str3);
}
执行结果:

可以看到,三个字符串的地址是不相同的,说明copy和 mutableCopy方法都是深复制。
不可变对象的copy与mutableCopy方法:
void testNoMutable()
{
NSString *str1 = @"test";
//直接copy是浅复制
NSMutableString *str2 = [str1 copy];
//copy返回的是不可变对象,str2不能被修改,因此会发生崩溃
//[str2 appendString:@"test"];
//mutableCopy是深复制
NSMutableString *str3 = [str1 mutableCopy];
[str3 appendString:@"test"];
NSLog(@"%@ %@ %@",str1,str2,str3);
NSLog(@"%p %p %p",str1,str2,str3);
}
执行结果:

可以看到:前两个地址一样,第三个地址不一样,因此不可变对象的copy方法是浅复制,mutableCopy方法是深复制。
另外需要注意:无论是可变对象还是不可变对象,copy 方法返回的对象都是不可变的。
2:集合对象的copy与mutableCopy
实际上,集合对象与非集合对象所遵循的规则基本上是一样的。
可变对象的的copy与mutableCopy 方法
验证代码:
void testSetMutable()
{
NSMutableArray *array1 = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c", nil];
//可变对象copy是深复制
NSMutableArray *array2 = [array1 copy];
//copy返回的是不可变对象,array2不能被修改,因此会崩溃
//[array2 addObject:@"d"];
//可变对象的mutableCopy是深复制
NSMutableArray *array3 = [array1 mutableCopy];
[array3 addObject:@"d"];
NSLog(@"%p %p %p",array1,array2,array3);
}
执行结果:

可以看到地址是不一样的。说明可变对象的copy和mutableCopy方法都是深复制。
不可变对象的copy与mutableCopy方法
验证代码:
void testSetNoMutable()
{
NSArray *array1 = @[@"a",@"b",@"c"];
//不可变对象的copy方法,浅复制
NSArray *array2 = [array1 copy];
//不可变对象的mutableCopy方法,深复制
NSArray *array3 = [array1 mutableCopy];
NSLog(@"%p %p %p",array1,array2,array3);
}
执行结果:

可以看到,前两个地址一样,第三个地址不一样。说明不可变对象的copy方法是浅复制,mutableCopy方法是深复制。
集合对象和非集合对象的一个差别:
上面说的集合对象的深复制并不是严格意义上的深复制,而是单层深复制。
单层深复制:对集合对象来说,深复制时只是将第一层对象进行了深复制,内部的对象仍然是浅复制。比如说
NSMutableArray *array1 = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c", nil];
调用copy方法 NSArray *array2 = [array1 copy] ,有分配了一块内存,array2指向了这块内存,但是数组内部的元素,指向的仍然是数组1内部的元素,即内部元素是浅复制。
验证代码:
void testSetMutable()
{
NSMutableArray *array1 = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c", nil];
//可变对象copy是深复制
NSMutableArray *array2 = [array1 copy];
//copy返回的是不可变对象,array2不能被修改,因此会崩溃
//[array2 addObject:@"d"];
//可变对象的mutableCopy是深复制
NSMutableArray *array3 = [array1 mutableCopy];
[array3 addObject:@"d"];
NSLog(@"%p %p %p",array1,array2,array3);
NSLog(@"%p %p %p",array1[],array2[],array3[]);
}
执行结果:

可以看到,三个数组的第一个元素的地址是一样的,也就是说内部元素是浅复制。
3:集合对象的完全复制
集合对象的完全复制,就是集合中的每一层的元素都是深复制。
方法一:
使用 initWith***: copyItems:YES 方法。
代码:
void testFullCopy()
{
NSMutableArray *array1 = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c", nil];
NSArray *array2 = [[NSArray alloc] initWithArray:array1 copyItems:YES];
NSLog(@"%p %p",array1,array2);
NSLog(@"%p %p",array1[],array2[]);
}
执行结果:

可以看到数组元素的地址不一样。
方法二:
先将集合进行归档,然后再解档。代码如下:
void testFullCopy2()
{
NSMutableArray *array1 = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c", nil];
NSArray *array2 = [NSKeyedUnarchiver unarchiveTopLevelObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:array1 ] error:nil];
NSLog(@"%p %p",array1,array2);
NSLog(@"%p %p",array1[],array2[]);
}
执行结果:

可以看到数组元素的地址不一样。
iOS中的深复制与浅复制的更多相关文章
- iOS 集合的深复制与浅复制
概念 对象拷贝有两种方式:浅复制和深复制.顾名思义,浅复制,并不拷贝对象本身,仅仅是拷贝指向对象的指针:深复制是直接拷贝整个对象内存到另一块内存中. 一图以蔽之 再简单些说:浅复制就是指针拷贝:深复制 ...
- Java中对象的深复制和浅复制详解
1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵ ...
- Java中的深复制与浅复制
1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不 复制它所引用的对象. ...
- C#中的深复制与浅复制
C#中分为值类型和引用类型,值类型的变量直接包含其数据,而引用类型的变量则存储对象的引用. 对于值类型,每个变量都有自己的数据副本,对一个变量的操作不可能影响到另一个变量.如 class Progra ...
- Java中的clone()----深复制,浅复制
这篇文章主要介绍了Java中对象的深复制(深克隆)和浅复制(浅克隆) ,需要的朋友可以参考下 1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他 ...
- js中的深复制与浅复制
前言 所谓深复制与浅复制(深拷贝与浅拷贝),乍一听感觉听高大上,像是一个非常难理解的概念,其实我们平常项目开发都是在用的,只是你可能不知道该怎么叫它的名字而已,就像你听熟了一首歌,就是不知道这首歌叫什 ...
- js中的深复制和浅复制
在实际情况中经常会遇到对对象复制的问题.比如在处理项目中的一笔多结构的数据存储或者调用,这个时候你就要对对象(json)进行操作,而不同的操作根据不同的需求来定义.其中最常见最普遍的是对对象的复制,重 ...
- iOS 之 深复制、浅复制
深复制不仅复制对象本身,对象持有的属性对象也做了复制. 浅复制之复制对象本身,不对里面的属性进行复制.
- 深复制与浅复制&&strong,copy修饰符总结
又是一个老生常谈的话题,可是貌似这个问题,好多ios开发工程师并不能理解透彻,所以简单记录分析一下深复制与浅复制的原理以及strong,copy修饰符的原理和使用. 一.深复制与浅复制 ...
- .Net深复制、浅复制
在.Net,大家都知道引用类型的深复制.浅复制吧. ,一般int等值类型是值类型(复制时是直接传值),一般的类(List<T>,Class)是引用类型(复制时传地址),默认是浅复制.若ob ...
随机推荐
- Uploadify 控件上传图片 + 预览
jquery的Uploadify控件上传图片和预览使用介绍. 在简单的servlet系统中和在SSH框架中,后台处理不同的,在三大框架中图片预览时费了不少力气,所以下面将两种情况都介绍一下. 1,前台 ...
- Ubuntu 12.04搭建Andorid编译环境
1.安装JDK,Android 5.0开始,开始使用OpenJDK 1.7,4.4等低版本是Oracke JDK1.6 install java environment // install open ...
- linux aio
前几天nginx的0.8.x正式成为stable,然后看了下代码,发现0.8加入了linux native aio的支持,我们知道在linux下有两种aio,一种是glibc实现的aio,这个比较烂, ...
- CPU占用率高分析方法步骤[转载]
由于涉及到私有代码,所有图片都隐去 1.执行TOP命令,确认CPU占用较高的进程PID 根据top命令,发现PID为8691的Java进程占用CPU高达3858%,出现故障 2.确认该进程中CPU占用 ...
- 怎么找到MyEclipse->add struts capabilities
问:MyEclipse:我的工程右键可以MyEclipse->add struts capabilities之前有,后来不知怎么就没有了,谁知道怎么弄出来是struts 答:你已经add过一次了 ...
- NopCommerce架构分析之六------自定义RazorViewEngine
系统中对Razor的支持包括两部分,其中之一就是自定义RazorViewEngine 一.自定义RazorViewEngine 在Global.asax.cs的Application_Start方法中 ...
- HDU 5317 RGCDQ
题意:f(i)表示i的质因子个数,给l和r,问在这一区间内f(i)之间任意两个数最大的最大公倍数是多少. 解法:先用筛法筛素数,在这个过程中计算f(i),因为f(i)不会超过7,所以用一个二维数组统计 ...
- (Android Studio)添加按钮以及权重问题
此文大部分摘自http://hukai.me/android-training-course-in-chinese/basics/firstapp/building-ui.html 注意到光标所在代码 ...
- -Xms 和 -Xmx 不能设置的太大
之前我一直有一个疑问,就是-Xms 和 -Xmx不是设置的越大越好吗?现在才明白怎么回事. 通过在命令行中执行 java 或者启动某种基于 Java 的中间件来运行 Java 应用程序时,Java 运 ...
- Swift之基础知识
Swift之基础知识 出于对Swift3.0的学习,写下这篇基本语法的笔记.希望能帮助记忆 -0- 这边提供Swift3.0中文教材,资源链接: https://pan.baidu.com/s/1c2 ...