iOS深拷贝与浅拷贝解析
来源:互联网 发布:淘宝拍下未付款15分钟 编辑:程序博客网 时间:2024/06/07 17:50
Apple官方文档如下:
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Collections/Articles/Copying.html
如果一个类想要正常调用copy和mutableCopy两个函数,那么类就一定要实现对应的NSCopying和NSMutableCopying协议。
例如NSString:
@interface NSString : NSObject <NSCopying, NSMutableCopying, NSSecureCoding>
1、元素数据的copy和mutableCopy。
常用的NSString类,示例代码如下:
NSString* string = @”a”;NSString* stringCopy = [string copy];// stringCopy与string地址相同,retainCount+ 1NSMutableString* stringMCopy = [string mutablecopy];// stringMCopy与string地址不同 NSMutableString* stringM1 = [stringMCopy copy];//地址与stringMCopy不同,且为不可修改NSMutableString* stringM2 = [stringMCopy mutablecopy];//地址与stringMCopy不同,可修改
可以基本推出NSString和NSMutableString中两个协议的实现:
NSString:- (id)copywithZone:(NSZone*)zone{ return self;} - (id)mutableCopywithZone:(NSZone*)zone{ NSMutableString* copy =[[NSMutableString alloc] initxxxxxx]; .... return copy;}NSMutableString:- (id)copywithZone:(NSZone*)zone{ NSString* copy = [[NSStringalloc] initxxxxxx]; .... return copy;//所以不可修改} - (id)mutableCopywithZone:(NSZone*)zone{ NSMutableString* copy =[[NSMutableString alloc] initxxxxxx]; .... return copy;}
2、容器类的copy和mutableCopy。
常用类NSArray和NSMutableArray,看如下示例代码:
Class1* obj1= ....;//正常初始化NSArray* array = [[NSArray alloc] initWithObjects:obj1, nil];NSArray* arrayCopy = [array copy];//地址不变,retaincount+1NSMutableArray* arrayMCopy = [array mutableCopy];//地址改变,但是数组中成员指针和obj1相同,浅拷贝NSMutableArray* arrayM1 = [arrayMCopy Copy];//地址改变,但是数组中成员指针和obj1相同,浅拷贝。arrayM1为NSArray不可修改NSMutableArray* arrayM2 = [arrayMCopy mutableCopy];//地址改变,但是数组中成员指针和obj1相同,浅拷贝
可以基本推出NSArray和NSMutableArray中两个协议的实现:
NSArray:- (id)copywithZone:(NSZone*)zone{ //伪码 return [self retain];}- (id)mutableCopywithZone:(NSZone*)zone{ NSMutableArray* copy = [[NSMutableString alloc] initxxxxxx]; for (id element in self) { [copy addObject:element];//element retian count + 1 .... } return copy;}NSMutableArray:- (id)copywithZone:(NSZone*)zone{ NSArray* copy = [[NSArray alloc] initXXX]; /*把每个element加入到copy数组,retainCount+1*/ .... return copy;}- (id)mutableCopywithZone:(NSZone*)zone{ NSMutableArray* copy = [[NSMutableString alloc] initxxxxxx]; for (id element in self) { [copy addObject:element];//element retian count + 1 .... } return copy;}
3、深拷贝
上面提到的官方文档中介绍两种实现深拷贝的方法:
a. 用Array的initWithArray: copyItems函数,如下:
NSArray *deepCopyArray=[[NSArray alloc] initWithArray: someArraycopyItems: YES];
调用后,会对原NSArray中的每个元素调用其copy函数,并把返回的id加入到新的数组中。所以这是依赖于Obj对象类实现的深拷贝,如果- (id)copywithZone:(NSZone*)zone是重新分配一块内存赋值后返回,那么就是真正的深拷贝。如果直接返回自身,那么它只是浅拷贝。
b. 用archiver方式:
NSArray* trueDeepCopyArray = [NSKeyedUnarchiverunarchiveObjectWithData: [NSKeyedArchiver archivedDataWithRootObject:oldArray]];
这是真正意义上的深拷贝,不依赖于实际类Copying协议的实现。
4. 用Category实现自定义的深拷贝deepmutableCopy,如:
- (NSMutableArray *)mutableDeepCopy{ NSMutableArray *ret = [[NSMutableArrayalloc] initWithCapacity:[self count]]; for (id value in self) { id oneCopy = nil; if ([value respondsToSelector:@selector(mutableDeepCopy)]) oneCopy = [value mutableDeepCopy]; else if ([value respondsToSelector:@selector(mutableCopy)]) oneCopy = [value mutableCopy]; if (oneCopy == nil) oneCopy = [value copy]; [ret addObject: oneCopy]; } return ret;}
思考:浅拷贝copy与retain的区别。
个人理解:对于不可变对象,例如NSString浅拷贝copy其实应该跟retain是一样的。虽然有这样的特例存在,但是copy与retain还是两个概念。
- iOS深拷贝与浅拷贝解析
- iOS深拷贝和浅拷贝解析
- 深拷贝与浅拷贝解析
- IOS中的深拷贝与浅拷贝
- IOS 深拷贝与浅拷贝
- iOS开发 深拷贝与浅拷贝
- iOS中的深拷贝与浅拷贝
- iOS伪拷贝, 浅拷贝, 深拷贝
- [ios]深拷贝,浅拷贝
- iOS深拷贝浅拷贝
- 深拷贝与浅拷贝(mutableCopy与Copy)详解 iOS
- python中的深拷贝与浅拷贝解析
- 深拷贝与浅拷贝的解析 (学习日记)
- C++浅拷贝与深拷贝的问题解析
- 深拷贝与浅拷贝
- 深拷贝与浅拷贝
- 深拷贝与浅拷贝
- “浅拷贝”与“深拷贝”
- HDU__2046 骨牌铺方格
- 机房收费系统安装过程
- 64bit eclipse jvm params
- 设计模式实现(八)--- 外观模式(Facade)
- Axure入门
- iOS深拷贝与浅拷贝解析
- hdu-2049-不容易系列之(4)——考新郎
- 九度题目1029:魔咒词典
- super用法
- Linux根文件系统无法正常显示命令提示符
- 1407291906-hd-Leftmost Digit.cpp
- POJ 1018 Communication System
- DHCP 服务器
- [思考]瞬时频率