iOS的深拷贝和浅拷贝

深拷贝和 浅拷贝的概念

首先在谈论iOS深拷贝和浅拷贝之前先给出对应概念
深拷贝 :浅拷贝并不拷贝对象本身,只是对指向对象的指针进行拷贝
浅拷贝 :直接拷贝对象到内存中一块区域,然后把新对象的指针指向这块内存

一个小小的注意事项

在iOS中并不是所有对象都支持Copy和MutableCopy,遵循NSCopying协议的类可以发送Copy协议,遵循NSMutableCopying协议的类可以发送MutableCopy消息。如果一个对象没有遵循这两个协议而发送Copy或者MutableCopy消息那么会发生异常。

同时如果要遵循NSCopying协议,那么必须实现copyWithZone方法。如果要遵循NSMutableCopying协议那么必须实现mutableCopyWithZone方法。

可变对象和不可变对象分别调用Copy和MutableCopy方法的区别

非集合类对象
分别调用 copy 和 mutableCopy 方法 如下

NSString *str = @"4065";
NSString *strCopy = [str copy];
NSMutableString *mustr = [str copy];
NSMutableString *muCopy = [str mutableCopy];
[mustr appendString:@"is hanhan"];    //会直接崩溃  (copy和mutableCopy的区别在于copy在复制对象的时候其实是返回了一个不可变对象,因此当调用方)
[muCopy appendString:@"is hanhan"];
NSLog(@"str = %@    strCopy = %@    mustr = %@    muCopy = %@",str,strCopy,mustr,muCopy);
NSLog(@"str地址%p    strCopy地址%p    mustr地址%p     muCopy地址%p",str ,strCopy,mustr,muCopy);

输出结果
在这里插入图片描述

上面可以看出对系统非集合类不可变对象调用Copy方法其实只是把当前对象的指针指向了原对象的地址,而调用mutableCopy方法则是新分配了一块内存区域并把新对象的指针指向了这块区域。对于可变对象来说调用Copy和MutableCopy方法都会重新分配一块内存

集合类容器

NSArray *array = [NSArray arrayWithObjects:@"hanhan",@"lengleng",@"gangjing",@"is 4065 ",nil];
NSArray *arrayCopy = [array copy];
NSMutableArray *muarray = [array copy];
NSMutableArray *copyArray = [array mutableCopy];
NSLog(@"array地址%p     arrayCopy地址%p      muarray地址%p     copyArray地址%p",array,arrayCopy,muarray,copyArray);

输出结果
在这里插入图片描述

NSMutableArray *muarray = [NSMutableArray arrayWithObjects:@"hanhan",@"lengleng",@"gangjing",@"is 4065 ",nil];
NSArray *array = [muarray copy];
NSArray *mutableCopy = [muarray mutableCopy];
NSMutableArray *muCopy = [muarray copy];
NSMutableArray *arrayCopy = [muarray mutableCopy];
NSLog(@"muarray地址%p   array地址%p   mutableCopy地址%p   muCopy地址%p   arrayCpy地址%p",muarray,array,mutableCopy,muCopy,arrayCopy);

在这里插入图片描述

由上面两个例子可知道
集合类对象的copy与mutableCopy:在集合类对象中,对 immutable 对象进行 copy,是指针复制, mutableCopy 是内容复制;对 mutable 对象进行 copy 和 mutableCopy 都是内容复制。但是:集合对象的内容复制仅限于对象本身,对象元素仍然是指针复制。用代码简单表示如下:
[immutableObject copy] // 浅复制
[immutableObject mutableCopy] //单层深复制
[mutableObject copy] //单层深复制
[mutableObject mutableCopy] //单层深复制

那么如何进行完全深复制呢?
我们在这里提供两种做法
第一种
NSDictionary shallowCopyDict = [[NSDictionary alloc] initWithDictionary:someDictionary copyItems:YES];

如果你用这种方法深复制,集合里的每个对象都会收到 copyWithZone: 消息。如果集合里的对象遵循 NSCopying 协议,那么对象就会被深复制到新的集合。如果对象没有遵循 NSCopying 协议,而尝试用这种方法进行深复制,会在运行时出错。copyWithZone: 这种拷贝方式只能够提供一层内存拷贝(one-level-deep copy),而非真正的深复制。

第二个方法是将集合进行归档(archive),然后解档(unarchive),如:
NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:oldArray]];

发布了34 篇原创文章 · 获赞 4 · 访问量 722

猜你喜欢

转载自blog.csdn.net/weixin_44824650/article/details/103218376