浅析ObjectiveC 深浅拷贝学习
来源:互联网 发布:淘宝上买号怎么领取 编辑:程序博客网 时间:2024/05/01 02:51
版权声明
此文版权归作者(chen1987lei)所有。欢迎非营利性转载,转载时必须包含原始链接http://www.cocoachina.com/bbs/read.php?tid=80463且必须包含此版权声明的完整内容。
iPhone开发语言Objective-C是一种简单的计算机语言,简称OC,支持复杂的面向对象编程。Objective C语言,通常写作ObjC和较少用的Objective C或Obj-C,是扩充C的面向对象编程语言。它主要使用于Mac OS X和GNUstep这两个使用OpenStep标准的系统,而在NeXTSTEP和OpenStep中它更是基本语言。ObjectiveC可以在gcc运作的系统写和编译,因为gcc含Objective C的编译器。
在ObjectiveC 中,什么是深浅拷贝? 深浅拷贝分别指深拷贝和浅拷贝,即mutableCopy和copy方法。
copy复制一个不可变对象,而mutableCopy复制一个mutable可变对象。
什么时候用到深浅拷贝?下面举几个例子说明。非容器类对象如NSString,NSNumber等一类对象
示例1:
// 非容器类对象
NSString *str = @"origin string";
NSString *strCopy = [str copy]; // 不可变
NSMutableString *mstrCopy = [str mutableCopy]; // 可变
[mstrCopy appendString:@"??"];
// 查看内存可以发现,str和strCopy指向的是同一块内存区域,我们称之为弱引用(weak reference)。而mstrCopy是真正的复制,系统为其分配了新的内存空间,保存从str复制过来的字符串值。从最后一行中修改这些值而不影响str和strCopy可以证明。
运行截图
示例2:
NSMutableString *mstr = [NSMutableString stringWithString:@"origin"];
NSString *strCopy = [mstr copy];
NSMutableString *mstrCopy = [mstr copy];
NSMutableString *mstrMCopy = [mstr mutableCopy];
// [mstrCopy appendString:@"1111"]; // error
[mstr appendString:@"222"];
[mstrMCopy appendString:@"333"];
// 以上四个对象所分配的内存都是不一样的。而且对于mstrCopy,它所指向的其实是一个imutable对象,是不可改变的,所以会出错,这点要注意,好好理解。
容器类对象深浅复制
比如NSArray,NSDictionary等。对于容器类本身,上面讨论的结论也适用,下面讨论的是复制后容器内对象的变化。
示例3:
// copy返回不可变对象,mutablecopy返回可变对象
NSArray *array1 = [NSArray arrayWithObjects:@"a",@"b",@"c",nil];
NSArray *arrayCopy1 = [array1 copy];
// arrayCopy1是和array同一个NSArray对象(指向相同的对象),包括array里面的元素也是指向相同的指针
NSLog(@"array1 retain count:%d",[array1 retainCount]); // 2
NSLog(@"array1 retain count:%d",[arrayCopy1 retainCount]); // 2
NSMutableArray *mArrayCopy1 = [array1 mutableCopy];
// mArrayCopy1是array1的可变副本,指向的对象和array1不同,但是其中的元素和array1中的元素指向的还是同一个对象。mArrayCopy1还可以修改自己的对象。
[mArrayCopy1 addObject:@"de"];
[mArrayCopy1 removeObjectAtIndex:0];
// array1和arrayCopy是指针复制,而mArrayCopy1是对象复制,符合前面示例1讨论的结论。mArrayCopy1可以改变其内的元素:删除或添加。但容器内的元素内容都是浅拷贝。
示例4:
NSArray *mArray1 = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
NSLog(@"mArray1 retain count: %d",[mArray1 retainCount]); // 1
NSArray *mArrayCopy2 = [mArray1 copy];
NSLog(@"mArray1 retain count:%d",[mArray1 retainCount]); // 2
// mArray1和mArrayCopy2指向同一对象,retain值+1
NSMutableArray *mArrayMCopy1 = [mArray1 mutableCopy];
NSLog(@"mArray1 retain count:%d",[mArray1 retainCount]); // mArrayCopy2和mArray1指向的是不一样的对象,但是其中的元素都是一样的对象--------同一个指针。
NSMutableString *testString = [mArray1 objectAtIndex:0];
// testString = @"1a1"; // 这样会改变testString的指针,其实是将@"1a1"临时对象赋给了testString
[testString appendString:@"tail"]; // 这样以上三个数组的首元素都被改变了
// 由此可见,对于容器而言,其元素对象始终是指针复制。如果需要元素对象也是对象复制,就需要实现深拷贝。
示例5:
NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"first"],[NSString stringWithString:@"b"],@"c",nil];
NSArray *deepCopyArray = [[NSArray alloc] initWithArray:array copyItems:YES];
NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:array]];
\
// trueDeepCopyArray是完全意义上的深拷贝,而deepCopyArray则不是,对于deepCopyArray内的不可变元素其还是指针复制。或者我们自己实现深拷贝的方法。因为如果容器的某一元素是不可变的,那你复制完后该对象仍旧是不能改变的,因此只需要指针复制即可。除非你对容器内的元素重新赋值,否则指针复制已足够。
// 举个例子,[[array objectAtIndex:0] appendString:@"sd"]后其他的容器内对象并不会受影响。[array objectAtIndex:1,2]和[deepCopyArray objectAtIndex:1,2]尽管是指向同一块内存,但是我们没有办法对其进行修改-----因为它是不可改变的。所以指针复制已经足够。所以这并不是完全意义上的深拷贝。
- 浅析ObjectiveC 深浅拷贝学习
- 浅析ObjectiveC 深浅拷贝学习
- 浅析ObjectiveC 深浅拷贝学习
- 浅析ObjectiveC 深浅拷贝学习
- 浅析ObjectiveC 深浅拷贝学习
- ObjectiveC 深浅拷贝学习
- ObjectiveC 深浅拷贝学习
- ObjectiveC 深浅拷贝学习
- ObjectiveC 深浅拷贝学习
- ObjectiveC 深浅拷贝学习
- ObjectiveC 深浅拷贝学习
- 浅析ObjectiveC 深浅拷贝学
- ObjectiveC 深浅拷贝(mutableDeepCopy)学习
- ObjectiveC 深浅拷贝(mutableDeepCopy)学习
- (转)ObjectiveC 深浅拷贝学习
- C++深浅拷贝浅析
- 【C++】 浅析深浅拷贝
- C++深浅拷贝浅析
- ffmpeg_sdk搭建
- Restart!记录工作生活的点点滴滴。
- 第三方开源类库搜集总结—IOS开发
- C++函数模板问题
- win7 定时关机
- 浅析ObjectiveC 深浅拷贝学习
- 使用IBM Rational Application Developer 8开发Portlet - Maven集成
- poj 3070(矩阵的快速幂)
- 恢复firefox关闭时保存标签页的提示。
- 在被窝里看书系列之《Windows PE 权威指南学习》笔记 第一章
- ubuntu12.04 中EMACS安装过程中关于crt*.o定位的问题
- 在被窝里看书系列之《Windows PE 权威指南学习》笔记 第二章
- sublime 看着太爽了!
- 代码优化如做游戏一样有趣