您的位置:首页 > 运维架构

浅谈深复制和浅复制

2014-03-09 16:38 197 查看

浅谈深复制和浅复制

转载请注明出处:http://blog.csdn.net/hzhenx1989/article/details/20847925

概念上的理解

深复制:拷贝一个对象,同时申请一份新的内容,返回一个新的地址指针,好比你有个钥匙,然后你去钥匙店复制了一把新的,跟原来的一模一样,都可以同一个锁

浅复制:把原来对象的地址指针赋值给另外一个指针,就像你家门口花盆有把钥匙,就你知道,但是有一天你告诉你妹纸,她也知道了,你们公用一把钥匙开锁。实际只有一把钥匙。如图



在oc上,苹果提供了copy的函数,可以让我们实现深复制。但是,如果你直接调用copy,编译的时候xcode没有报错,但是运行的时候,xcode会报错,结果如下:

2014-03-09 16:22:44.369 Prototype[952:303] -[Prototype copyWithZone:]: unrecognized selector sent to instance 0x100109b40
2014-03-09 16:22:44.371 Prototype[952:303] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Prototype copyWithZone:]: unrecognized selector sent to instance 0x100109b40'
*** First throw call stack:
(
0   CoreFoundation                      0x00007fff8c33e716 __exceptionPreprocess + 198
1   libobjc.A.dylib                     0x00007fff85582470 objc_exception_throw + 43
2   CoreFoundation                      0x00007fff8c3d4d5a -[NSObject(NSObject) doesNotRecognizeSelector:] + 186
3   CoreFoundation                      0x00007fff8c32cc3e ___forwarding___ + 414
4   CoreFoundation                      0x00007fff8c32ca28 _CF_forwarding_prep_0 + 232
5   Prototype                           0x00000001000018cf main + 143
6   Prototype                           0x0000000100001834 start + 52
7   ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminate called throwing an exception


可见,这个是需要实现如下一个函数

- (id)copyWithZone:(NSZone *)zone;


这个函数是NSCopying协议,所以在使用copy对象的时候要继承这个协议,然后实现这个方法。具体如下

- (id)copyWithZone:(NSZone *)zone
{
return [[[self class] allocWithZone:zone] init];
}
这个方法在苹果官方文档说

Returns a new instance that’s a copy of the receiver. (required)
The returned object is implicitly retained by the sender, who is responsible for releasing it. The copy returned is immutable if the consideration “immutable vs. mutable” applies to the receiving object; otherwise the exact nature of the copy is determined by the class.
可见,这个copy是复制一个immutable的对象,也就是不可修改的对象。简单的理解,就是如果是一个NSMutableString对象,如果采用copy,copy出来的对象,也是一个不可修改的NSString对象,而不是MutableString。那么,苹果同样提供了另外一个协议,支持mutablecopy

@protocol NSMutableCopying

- (id)mutableCopyWithZone:(NSZone *)zone;

@end
根据文档说的
The returned object is implicitly retained by the sender, which is responsible for releasing it. The copy returned is mutable whether the original is mutable or not.


我们可以知道,这个方法是返回一个可以修改的,不管之前那个是否可以修改,也就是说,如果一个NSString对象,通过mutableCopy方式 ,复制出来的对象就是NSMutableString。

但是这里可能有个误区。假设我们有A对象,然后我们执行B = [A copy];这样B就是A的一个复制品。但是这不等同于clone。按照我的理解,clone是要对着原型克隆一个一模一样的对象出来 ,但是copy按道理应该也是。假设A对象是如下

@interface A : NSObject<NSCopying>

@property(nonatomic, copy) NSString *name;

@end


然后我们 通过这样
A *a = [[A alloc] init];
A.name = @"I am b !";//原来初始值为@"I am A object!"
A *b = [a copy];
NSLog(@"b object's name is %@", b.name);//结果是 i am b ;

可以看出,copy只是按照初始化的时候把对象赋值一个,而不是把当前最新的数据copy。如果要真正做到clone,需要在copy对象之后,把原来的值赋值一遍,这样才真正的clone。

对于浅赋值,这里不详细讲了,比较简单,就是一个指针引用。不会涉及内存的增长。

转载请注明出处:http://blog.csdn.net/hzhenx1989/article/details/20847925
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息