深浅复制
来源:互联网 发布:现在淘宝客好做吗 编辑:程序博客网 时间:2024/05/18 01:29
copy:
返回由copyWithZone:返回的对象。
- (id)copy
返回值:
对象由NSCopying协议方法 copyWithZone:返回;
描述:
这是采用了NSCopying协议的对象的简便方法。如果对象没有实现copyWithZone:,将会抛出异常。NSObject自己并不支持 NSCopying协议,他的子类必须支持NSCopying协议,并实现 copyWithZone:方法。子类中的copyWithZone:应该先调用父类中的版本,除非子类是直接继承自NSObject
mutableCopy
返回由 mutableCopyWithZone:返回的对象,其中zone参数为nil。
- (id)mutableCopy;
返回值:
对象由NSMutableCopying协议方法 mutableCopyWithZone:返回,zone参数为nil。
描述:
这是采用了 NSMutableCopying协议的类的便利方法,如果这个类型没有实现mutableCopyWithZone:方法,将会产生异常。
验证:非可变对象不能用mutableCopy;
例子:
CopyTestObject 继承自 NSObject
代码:
CopyTestObject* obj = [[CopyTestObject alloc] init]; CopyTestObject* copyObj = [obj copy]; NSLog(@"obj address:%p",obj); NSLog(@"obj address:%p",copyObj);运行正常,输出
obj address:0xa06a6a0
obj address:0xa069b80
代码:
CopyTestObject* obj = [[CopyTestObject alloc] init];CopyTestObject* mutableCopyObj = [obj mutableCopy];
出现异常NSInvalidArgumentException
reason: '-[CopyTestObject mutableCopyWithZone:]: unrecognized selector sent to instance 0x9a847d0'
验证:可变对象,用copy得到的为非可变对象。用mutableCopy得到可变对象。
例子2:
NSArray* array = [[NSArray alloc] init]; NSArray* copyArray = [array copy]; NSMutableArray* mutArray = [[NSMutableArray alloc] init]; NSMutableArray* copyMutArray = [mutArray copy]; NSMutableArray* mutArray2 = [[NSMutableArray alloc] init]; NSMutableArray* copyMutArray2 = [mutArray mutableCopy]; NSLog(@"array class:%@",[NSString stringWithUTF8String:object_getClassName(array)]); NSLog(@"copyArray class:%@",[NSString stringWithUTF8String:object_getClassName(copyArray)]); NSLog(@"mutArray class:%@",[NSString stringWithUTF8String:object_getClassName(mutArray)]); NSLog(@"copyMutArray class:%@",[NSString stringWithUTF8String:object_getClassName(copyMutArray)]); NSLog(@"mutArray2 class:%@",[NSString stringWithUTF8String:object_getClassName(mutArray2)]); NSLog(@"copyMutArray2 class:%@",[NSString stringWithUTF8String:object_getClassName(copyMutArray2)]);
输出:
2014-04-11 10:38:27.257 testCopy[4759:a0b] array class:__NSArrayI2014-04-11 10:38:27.257 testCopy[4759:a0b] copyArray class:__NSArrayI2014-04-11 10:38:27.257 testCopy[4759:a0b] mutArray class:__NSArrayM2014-04-11 10:38:27.258 testCopy[4759:a0b] copyMutArray class:__NSArrayI2014-04-11 10:38:27.258 testCopy[4759:a0b] mutArray2 class:__NSArrayM2014-04-11 10:38:27.258 testCopy[4759:a0b] copyMutArray2 class:__NSArrayM
NSCopying协议:
NSCopying协议声明了一个方法来拷贝一个对象。拷贝的确切意义可能根据不同个类型而变化,但是拷贝的对象必须是一个功能独立的对象,其中包含的值和原对象相同在拷贝完成时。拷贝产生的对象被调用者保留,以在适当的时候释放他。
NSCopying定义了一个方法copyWithZone:,但是拷贝通常通过简便函数copy调用。copy函数在所有继承自NSObject的对象中都有定义,用来方便的调用copyWithZone:,其中参数为默认zone(内存区域)。
在如下情况你可以选择实现协议:
1.实现NSCopying来使用alloc和init,在那些没有继承copyWithZone:的类别中。
3.实现NSCopying,在某些内容不可变的类别中,以保留计数来代替创建一个新的拷贝。(自定义对象的拷贝含义)
如果子类从父类继承NSCopying,而且声明了额外的成员变量,子类必须去重写copyWithZone:,以正确的操作自己的成员变量,当然要先调用父类的实现。
实例方法:
- (id)copyWithZone:(NSZone *)zone
返回一个新的实例,这个实例是发送者的拷贝。
参数:
内存中被分配给新实例的一块区域,如果zone的值为NULL,则新实例从默认的区域中分配,这块默认的区域由NSDefaultMallocZone返回。
描述:
拷贝返回一个不可变类型,如果接收者需要考虑可变与不可变。否则复制的具体情况由类型决定。
NSMutableCopying协议:
NSMutableCopying协议声明了了一个方法来提供可变对象的副本。只有定义了可变与不可变差别的类型能采用改协议。那些没有这些差别的类型,应采取NSCopying协议。
NSMutableCopying协议中声明了一个方法,mutableCopyWithZone:,但是可变拷贝通常通过便利方法mutableCopy来调用。mutableCopy方法在所用的NSObject对象中都有定义,以便更方便的调用mutableCopyWithZone:方法。
如果子类从父类继承NSMutableCopying协议,并且声明了额外的实例变量,子类需要去重构 mutableCopyWithZone:来正确的操作他自己的实例变量,当然首先应该调用父类的实现。
实例方法:
- (id)mutableCopyWithZone:(NSZone *)zone
参数
zone
内存中被分配给新实例的一块区域,如果zone的值为NULL,则新实例从默认的区域中分配,这块默认的区域由NSDefaultMallocZone返回。
描述
这个拷贝返回的是可变对象,无论原对象是可变的或不可变的。
关于数组的深浅拷贝
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Collections/Articles/Copying.html
无论用copy还是mutablecopy得到的都是数组的浅拷贝。
数组的深拷贝
NSArray *deepCopyArray=[[NSArray alloc] initWithArray:someArray copyItems:YES];其中数组中的元素要实现方法:
- (id)copyWithZone:(NSZone *)zone
验证例子:
@interface CopyTestObject : NSObject@property (nonatomic, copy)NSString* thename;@property (nonatomic, retain)NSString* myname;@end
@implementation CopyTestObject- (id)copyWithZone:(NSZone *)zone{ CopyTestObject *result = [[[self class] allocWithZone:zone] init]; result.myname = [self.myname copy]; result.thename = [self.thename copy]; return result;}@end
NSMutableArray* mutArray =[[NSMutableArray alloc] init]; { CopyTestObject* obj = [[CopyTestObject alloc] init]; obj.thename = @"name1111111"; obj.myname = @"myname1111111"; [mutArray addObject:obj]; } { CopyTestObject* obj = [[CopyTestObject alloc] init]; obj.thename = @"name22222222"; obj.myname = @"myname22222222"; [mutArray addObject:obj]; } NSArray* copyArray = [[NSMutableArray alloc] initWithArray:mutArray copyItems:YES]; CopyTestObject* obj1 = [mutArray objectAtIndex:0]; obj1.thename = @"name change"; obj1.myname = @"myname change"; for (CopyTestObject* obj in mutArray) { NSLog(@"mutArray:%@ %@",obj.thename,obj.myname); } for (CopyTestObject* obj in copyArray) { NSLog(@"copyArray:%@ %@",obj.thename,obj.myname); }输出:
2014-04-11 10:49:12.581 testCopy[4779:a0b] mutArray:name change myname change2014-04-11 10:49:12.582 testCopy[4779:a0b] mutArray:name22222222 myname222222222014-04-11 10:49:12.582 testCopy[4779:a0b] copyArray:name1111111 myname11111112014-04-11 10:49:12.582 testCopy[4779:a0b] copyArray:name22222222 myname22222222
- 深浅复制
- 深浅复制
- 深浅复制
- 深浅复制
- 深浅复制
- 深浅复制
- 深浅复制
- 关于深浅复制
- java深浅拷贝(复制)
- java深浅拷贝(复制)
- c#深浅复制
- 原型模式深浅复制
- [Python] List & 深浅复制
- iOS深浅复制
- OC中的深浅复制
- oc笔记-深浅复制
- OC深浅复制问题
- java中的深浅复制
- ios 学习之 NSPredicate 模糊、精确、查询
- 时间戳服务原理
- 【转】Http和Socket区别
- 为项目自动添加构建路径
- 阻碍数据中心扩展的几大因素
- 深浅复制
- 用OpenSceneGraph实现的NeHe OpenGL教程 - 第十九课_附录1
- 【RequireJS--API学习笔记】
- 【JSTL】jstl 1.1
- request.getSchema()+"://"+request.getServerName()+":"+request.getServerPort+path+"/"
- PendingIntent详解
- 谷歌眼镜将要开始限时发售,你准备好了吗?
- Java中“异常机制”深入研究(一)
- 使用secure CRT的SFTP在LINUX与WINDOWS下交换文件