iOS学习笔记13—NSCopying
如果要调用一个对象的copy方法,这个对象必须遵循NSCopying的协议。这个协议中规定了一个方法:- (id)copyWithZone:(NSZone *)zone;我们就是通过实现这个方法给对象提供拷贝的功能。对于很多现有类,如NSString,NSDictionary,。。。这个方法已经实现。假设我们现在自定义了一个类,需要为这个类提供拷贝的功能,就需要自己来动手写CopyWithZone的方法。
NSCopying协议声明了一个方法,提供拷贝一个对象的功能。关于“copy”的确切含义有太多版本,但任何含义的copy都必须保证在copy完成后生成的对象与源对象保持相同值(即生成一个新的实例,然后把其成员都按原实例赋值)。NSCopying的copy消息发送者负责retain和release。
NSCopying声明了copyWithZone方法,但通常是简单的调用copy方法,copy方法继承自NSObject,在copy内部简单的带默认zone参数调用了copyWithZone。
下面是完成NSCopying的可选项:
1、实现NSCopying:不继承copyWithZone:的类,使用alloc和init...。
2、实现NSCopying:继承copyWithZone:的类,调用父类的copyWithZone:。如果超类的实现使用NSCopyObject功能,必须对retain对象的指针实例变量作出明确的指派。
3、实现NSCopying:通过retain原有的,而不是创建一个新的副本,如果类和它的内容是不可改变的。
如果子类从它的超类继承NSCopying,并声明了额外的实例变量,子类在重写copyWithZone:妥善处理自己的实例变量之前需先调用父类的实现。
如果想要区分可变副本和不可变副本,那么copyWithZone:应该返回不可变副本,而mutableCopyWithZone:应该返回可变副本。产生对象的可变副本并不要求被复制的对象本身也是可变的(反之亦然)。
类的设计者必须确定是否在NSCopying中实现浅复制或深复制,并为其编写文档,以告知类的使用者。
下面的内容是转载的
1.简单复制只能实现浅拷贝:指针赋值,使两个指针指向相同的一块内存空间,操作不安全。
2. Foundation类已经遵守了<NSCopying>和 <NSMutableCopying>协议,即实现了copy和mutableCopy方法,因此Foundation对象可以使用这些方法创建对象的副本或可变副本
@protocol NSCopying
- (id)copyWithZone:(NSZone *)zone;
@end
@protocol NSMutableCopying
- (id)mutableCopyWithZone:(NSZone *)zone;
@end
3.用户自定义类遵守<NSCopying>协议和<NSMutableCopying>协议,则必须实现copyWithZone方法和mutableCopyWithZone方法,否则该类对象无法响应copy和mutableCopy消息
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];
实现stu2是stu1的副本,这里是深复制,stu1和stu2分别对应不同内存。
5.如果你的类产生了子类,那么copyWithZone:方法也将
被继承
Student *stu = [[Student allocWithZone: zone] init];
该方法应该改为: Student *stu = [[[self class]allocWithZone: zone]init];
如果编写一个类的copyWithZone:方法那么子类的方法应该先调用父类的copy方法以复制继承来的copy实例变量.