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 ...
随机推荐
- WCF服务运行一段时间后客户端无法连接WCF服务的解决办法 (转)
WCF服务运行一段时间后客户端无法连接WCF服务的解决办法 (转) Windows Communication Foundation (WCF)是Microsoft为构建面向服务的应用提供的分布式通信 ...
- MSSQL复制功能实现与Oracle数据库同步
1.分别建立链接对数据库进行操作,SQLServer可以用ADO.NET,操作Oracle可以用OLEDB或者用System.Data.OracleClient(需要添加引用才能用) 这种方案的优点就 ...
- Android开发框架之xUtils学习
1.一个非作者弄的xUtils API文档: http://xutilsapi.oschina.mopaas.com/overview-summary.html 2.使用xUtils用户的一些博客文档 ...
- Java盲点:双重检查锁定及单例模式
尊重原创: http://gstarwd.iteye.com/blog/692937 2004 年 5 月 01 日 所有的编程语言都有一些共用的习语.了解和使用一些习语很有用,程序员们花费宝贵的时间 ...
- MySQL优化器 limit影响的case
测试的用例中,因为limit的大小不同,而产生了完全不同的执行计划: 1. 测试case: create table t1 ( f1 ) not null, f2 ) not null, f3 ) n ...
- 【众秒之门 JavaScript与jQuery技术精粹 #BOOK#】第1章 初学JavaScript需知的七件事
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8& ...
- Java传参那些事!
刚刚学习java传参的时候很纠结,也非常的不理解!课本上的“按值传递”和“按址传递”搞的自己是一头雾水,后来写的项目多了,自然就明白了! 现在写传参几乎就是条件反射一般——“秒成”,分享当初自己为此写 ...
- 【转】禁止seekbar的拖动事件
原文网址:http://blog.csdn.net/ansionnal/article/details/8229801 当然是可以的! 其实是 onTouchEvent 事件时,不让他传递事件就行了! ...
- 【转】Windows环境下Android NDK环境搭建
原文网址:http://www.metsky.com/archives/525.html 前面介绍Windows下Android 开发环境配置,主要是面向JAVA开发环境,对只做APK上层应用开发人员 ...
- 数学(扩展欧几里得算法):HDU 5114 Collision
Matt is playing a naive computer game with his deeply loved pure girl. The playground is a rectangle ...