iOS-深浅拷贝
2015-12-30 15:34
232 查看
首先关于copy和mutableCopy的行为:不管是NSString这种元素类、还是NSArray这样的容器类、还是Mutable和非Mutable类,copy和mutableCopy调用后表现的行为到底是什么样完成取决于类本身NSCopying和NSMutableCopying协议是如何实现的。
想要正常调用copy和mutableCopy两个函数,那么类就一定要实现对应的协议。
1. 元素数据的copy和mutableCopy。
常用的NSString类,示例代码如下:
可以基本推出NSString和NSMutableString中两个协议的实现
2. 容器类的copy和mutableCopy。
常用类NSArray和NSMutableArray,看如下示例代码:
//推断
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,如:
原文地址:http://blog.csdn.net/omegayy/article/details/7311839
想要正常调用copy和mutableCopy两个函数,那么类就一定要实现对应的协议。
1. 元素数据的copy和mutableCopy。
常用的NSString类,示例代码如下:
NSString* string = @”a”; NSString* stringCopy = [string copy];// stringCopy与string地址相同,retainCount+ 1 NSMutableString* 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+1 NSMutableArray* arrayMCopy = [array mutableCopy];//地址改变,但是数组中成员指针和obj1相同,浅拷贝 NSMutableArray* arrayM1 = [arrayMCopy Copy];//地址改变,但是数组中成员指针和obj1相同,浅拷贝。arrayM1为NSArray不可修改 NSMutableArray* arrayM2 = [arrayMCopy mutableCopy];//地址改变,但是数组中成员指针和obj1相同,浅拷贝
//推断
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; }
原文地址:http://blog.csdn.net/omegayy/article/details/7311839
相关文章推荐
- iOS事件机制
- 使用Xcode和Instruments调试解决iOS内存泄露
- iOS 长按手势
- iOS汉字转成拼音
- ios使用 KVC 修改textField的placeholder的字体颜色和大小
- iOS 调试 crash breakpoint EXC_BAD_ACCESS SIGABRT(转)
- iOS开发-进阶:代理设计模式简介
- iOS经典讲解之Socket使用教程
- ios开发----应用数据存储的常用方法之plist存取方法
- iOS打开外部应用、浏览器
- IOS 学习blog
- iOS开发拓展篇—音频处理(音乐播放器6)
- iOS开发 第一天 创建HelloWorld
- iOS中JSONModel的使用
- IOS开发 - TextField 控件详细
- iOS中AutoLayer自动布局流程及相关方法
- iOS开发-进阶: NSNotificationCenter 通知机制简介
- IOS-自动布局详解
- iOS后台运行机制详解(二)
- iOS7之后的各种bar和布局