拷贝----浅拷贝,深拷贝(copy),引用计数拷贝及区别

2017-11-29  本文已影响13人  有理想有暴富的小青年

在iOS中,我们有时要用到copy的方法。对对象进行拷贝。总结了一下拷贝。

1)iOS拷贝都有哪些?

拷贝有三种:浅拷贝,引用计数拷贝,深拷贝。接下来我一一总结。先码后理。

1、浅拷贝

FYWork *w = [[FYWork alloc] init];

__weak FYWork *w1 ;

w1 = w;

w1浅拷贝w 前面用__weak关键字修饰,只是指向w所开辟的空间,但是不持有这块空间。RC值为1.所以当w指针释放的时候,w1的指针变为nil。

2、引用计数拷贝

FYWork *w = [[FYWork alloc] init];

__strong FYWork *w1 ;

w1 = w;

w1引用计数拷贝了w前面用__strong关键字修饰 不仅指向w所开辟的空间。而且还持有w的空间。RC值为2.当w指针释放的时候,w1没有影响

3、深拷贝

FYWork *w = [[FYWork alloc] init];

w.name = @“feng yong”;

FYWork *w1 = [[FYWork alloc]init];

w1.name = w.name;

w1深拷贝了w 是开辟了两块不同的空间,w1指向自己的空间并持有,w也指向自己的空间并持有。RC值为2.并且,当w的name值改变,也和w1的name属性无关

copy的用法:

FYWork *w = [[FYWork alloc] init];

FYWork *w1 = [w copy];

但是,使用copy有两个需要做的事:

1.在调用copy方法的对象的类.h中要遵守NSCopying协议

2.在调用copy方法的对象的类.h中要重写allocWithZone方法

以上原文地址:http://blog.csdn.net/fydevelop/article/details/53837420

加:为什么要实现以上两个方法

NSCopiny

NSCopying是一个与对象拷贝有关的协议。如果想让一个类的对象支持拷贝,就需要让该类遵守并实现NSCopying协议。NSCopying协议中的方法只有一个- (id)copyWithZone:(NSZone *)zone。当我们的类遵守了NSCopying协议,通过类的对象调用copy方法时,copy方法就会去调用我们实现的- (id)copyWithZone:(NSZone *)zone方法,实现拷贝功能。实现代码如下所示:

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

Person *model = [[[self class] allocWithZone:zone] init];

model.firstName = self.firstName;

model.lastName  = self.lastName;

//未公开的成员

model->_nickName = _nickName;

return model;

}

说明:在- (id)copyWithZone:(NSZone *)zone方法中,一定要使用通过[self class]方法 返回的对象去调用allocWithZone:方法。因为指针可能实际指向的是Person的子类,例如:Student、Teacher。这种情况下,通过调用[self class],就可以返回正确的类的类型对象。

NSMutableCopying

NSCopying协议与NSMutableCopying的区别主要是在于,返回的对象是否是可变类型的。以Foundation框架的NSArray为例

NSArray *nameArray = @[@"Jim", @"Tom", @"David"];

NSArray *copyArray = [nameArray copy];

NSMutableArray *mutableCopyArray = [nameArray mutableCopy];

[mutableCopyArray addObject:@"Sam"];

`

`NSArray对象调用copy方法时,copy方法会调用-(id)copyWithZone:(NSZone *)zone,得到对象的一份拷贝,但得到的对象还是不可变的对象。而NSArray对象调用mutableCopy方法时,mutableCopy方法会调用- (id)mutableCopyWithZone:(NSZone *)zone,得到可变的对象。

因此,如果自定义类具有可变和不可变的区别,想让它支持拷贝时,就需要同时实现NSCopying和NSMutableCopying,在- (id)copyWithZone:(NSZone *)zone返回的是不可变对象,在- (id)mutableCopyWithZone:(NSZone *)zone返回的是可变对象。

上一篇下一篇

猜你喜欢

热点阅读