​NSCopying

NSCopying


如果要调用一个对象的copy方法,这个对象必须遵循NSCopying的协议。这个协议中规定了一个方法:-
(
id)copyWithZone:(NSZone *)zone;我们就是通过实现这个方法给对象提供拷贝的功能。对于很多现有类,如NSStringNSDictionary,。。。这个方法已经实现。假设我们现在自定义了一个类,需要为这个类提供拷贝的功能,就需要自己来动手写CopyWithZone的方法。


NSCopying协议声明了一个方法,提供拷贝一个对象的功能。关于“copy”的确切含义有太多版本,但任何含义的copy都必须保证在copy完成后生成的对象与源对象保持相同值(即生成一个新的实例,然后把其成员都按原实例赋值NSCopyingcopy消息发送者负责retainrelease


NSCopying声明了copyWithZone方法,但通常是简单的调用copy方法,copy方法继承自NSObject,在copy内部简单的带默认zone参数调用了copyWithZone

下面是完成NSCopying的可选项:

1、实现NSCopying:不继承copyWithZone:的类,使用allocinit...

2、实现NSCopying:继承copyWithZone:的类,调用父类的copyWithZone:。如果超类的实现使用NSCopyObject功能,必须对retain对象的指针实例变量作出明确的指派。

3、实现NSCopying:通过retain原有的,而不是创建一个新的副本,如果类和它的内容是不可改变的。

如果子类从它的超类继承NSCopying,并声明了额外的实例变量,子类在重写copyWithZone:妥善处理自己的实例变量之前需先调用父类的实现。


如果想要区分可变副本和不可变副本,那么copyWithZone:应该返回不可变副本,而mutableCopyWithZone:应该返回可变副本产生对象的可变副本并不要求被复制的对象本身也是可变的(反之亦然)


类的设计者必须确定是否在NSCopying中实现浅复制或深复制,并为其编写文档,以告知类的使用者。


下面的内容是转载的

1.简单复制只能实现浅拷贝:指针赋值,使两个指针指向相同的一块内存空间,操作不安全。

2. Foundation类已经遵守了<NSCopying> <NSMutableCopying>协议,即实现了copymutableCopy方法,因此Foundation对象可以使用这些方法创建对象的副本或可变副本


@protocol NSCopying


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

@end

@protocol NSMutableCopying

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

@end


3.用户自定义类遵守<NSCopying>协议和<NSMutableCopying>协议,则必须实现copyWithZone方法和mutableCopyWithZone方法,否则该类对象无法响应copymutableCopy消息

4.实现copyWithZone方法,例:

-(id)copyWithZone:(NSZone *)zone

{

    Student *stu = [[Student allocWithZone:zone]initWithName:self.name Age:self.age];

   return stu;

}

对应main函数中:假设已经有一个Student对象stu1

则:Student stu2 = [stu1 copy];

实现stu2stu1的副本,这里是深复制,stu1stu2分别对应不同内存。


5.如果你的类产生了子类,那么copyWithZone:方法也将

被继承

Student *stu = [[Student allocWithZone: zone] init];

该方法应该改为: Student *stu = [[[self class]allocWithZone: zone]init];

如果编写一个类的copyWithZone:方法那么子类的方法应该先调用父类的copy方法以复制继承来的copy实例变量.


你可能感兴趣的:(​NSCopying)