2018.08.27 19:54* 字数 533 阅读 979评论 2喜欢 0
copyWithZone
copyWithZone是NSCopying协议的方法,只有实现了copyWithZone方法的对象才能够进行copy的操作。像NSArray、NSMutableArray,NSDictionary、NSMutableDictionary等内部都实现了copyWithZone方法才能进行copy操作。
NSObject类有copyWithZone和MutableCopyWithZone两个类方法,但是其本身并没有实现,它要求子类去实现,子类要调用copy方法进行复制,必须遵循NSCopying协议实现copyWithZone方法,否则会崩溃。
copy有浅拷贝和深拷贝,具体想要实现哪一种,可以在copyWithZone和MutableCopyWithZone方法里面自定义实现。copy和mutableCopy操作分别对应copyWithZone和MutableCopyWithZone方法。
对于不可变对象,浅拷贝为指针拷贝,深拷贝为复制不可变副本
对于可变对象,浅拷贝为不可变副本,深拷贝为可变副本
如果我们想用我们的某个类需要区别对待这两个功能——同时提供创建可变副本和不可变副本的话,一般在NSCopying协议规定的方法 copyWithZone中返回不可变副本;而在NSMutableCopying的mutableCopyWithZone方法中返回可变副本。然后调 用对象的copy和mutableCopy方法来得到副本。
很少自定义可变类型的类,所以我们可以copyWithZone实现指针拷贝或副本拷贝,这完全取决于作者意愿以及业务需求
例如我想将copyWithZone方法用于浅拷贝,即指针拷贝
有一个Product类
@interface Product :NSObject<NSCopying>
@property (strong, nonatomic) NSString* name;
@end
//浅拷贝
@implementation Product
- (id)copyWithZone:(NSZone *)zone {
return self;
}
@end
或者想将copyWithZone方法用于深拷贝,即副本拷贝
//深拷贝
@implementation Product
- (id)copyWithZone:(NSZone *)zone {
Product *copy = [[Product allocWithZone] init];
copy.name = self.name; //属性赋值,多个属性时同理
return copy; //返回副本
}
注意的一点,当Product有子类时,需要这样写Product *copy = [[[self class] allocWithZone] init];
因为copyWithZone会被继承,当子类使用copy方法时,最终会调用到父类的copyWithZone方法
}
allocWithZone