当谈到对象复制时都绕不开浅复制与深复制的区分,它们是什么意思呢?
在OC中,因为采用内存计数的方式管理内存,所以浅复制时会对同一个内容计数加一,深复制则不会。
在OC中,复制操作有copy和mutableCopy两种方法,那哪种是浅复制哪种是深复制呢?
先把对象大致分为两类:非集合对象与集合对象,至于为什么要这么分,待会讲集合对象的时候再说。
非集合对象就是指NSString、NSNumber等本身就是具体内容的对象。像NSString这种对象,还有一个相关的叫NSMutableString。所以在非集合对象中又可以分为可变对象和不可变对象。
对他们进行copy与mutableCopy的含义是:
用代码来看如下:
NSString *string = @"origin";
NSString *stringCopy = [string copy];// 浅复制
NSMutableString *stringMCopy = [string mutableCopy];// 深复制
NSMutableString *string = [NSMutableString stringWithString: @"origin"];
NSString *stringCopy = [string copy];// 深复制
NSMutableString *mStringCopy = [string copy];// 深复制
NSMutableString *stringMCopy = [string mutableCopy];// 深复制
[mStringCopy appendString:@"mm"]; // crash
上面说了非集合对象,那什么是集合对象呢?集合对象就是指NSArray、NSDictionary、NSSet这些包含其他对象的对象。
为什么要做这个区分呢?因为浅复制、深复制这两个概念其实并不完全,更准确的应该分为三种:浅复制、深复制、完全深复制。
在OC中,当你对一个集合对象做深复制时,这个深复制只是单层的,集合内的元素对象其实还只是引用,并不是每一层都是深复制,这一情况,苹果定义为单层深复制(one-level-deep copy)。只有对集合内的每一层都去做深复制,才能够称为完全深复制。
先说说简单的浅复制与深复制,其实与非集合对象差不多:
代码来说就是:
NSArray *array = @[@[@"a", @"b"], @[@"c", @"d"];
NSArray *copyArray = [array copy];// 浅复制
NSMutableArray *mCopyArray = [array mutableCopy];// 单层深复制
NSMutableArray *array = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
NSArray *copyArray = [array copy];// 单层深复制,返回不可变对象
NSMutableArray *mCopyArray = [array mutableCopy];// 单层深复制
那如果要做完全深复制该怎么做呢?
有两种方法:
NSDictionary shallowCopyDict = [[NSDictionary alloc] initWithDictionary:someDictionary copyItems:YES];
copyItems设为YES会对集合中的每一个对象尝试做深复制,但是要求集合中的元素对象遵循NSCopying 协议,否则就会报错。但这其实还是对元素这一层的单层深复制,再下去也没有完全深复制。
NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:oldArray]];
以上就是OC中浅复制与深复制的各种应用了,要自己测试到底操作是浅复制还是深复制,可以通过看对象的引用计数是否增加:
NSLog(@"mArray retain count: %d", [mArray retainCount]);// ARC下不可用
或者直接看两个对象的地址是否一致:
NSLog(@"string自身指针的地址:%x", &str);
NSLog(@"string指针指向的对象的地址:%p", str);
版权所有:http://blog.csdn.net/cloudox_