对于 NSString 和 NSArray,因为已经实现了 NSCopying 协议的相关方法,因此可以直接调用 copy方法,而对于自定义类,因为没有接受和实现 NSCopying协议,不能直接调用 copy 方法,需要自己实现协议中的相关方法,以下为简单示例:
以 Person 类为例.
@interface Person : NSObject<NSCopying> //需要接受NSCopying协议
@property (nonatomic, retain)NSString * name;
@property (nonatomic, retain)NSString * sex;
- (void)setName:(NSString *)name
sex:(NSString *)sex;
@end
Person 的.m 文件
#import "Person.h"
@implementation Person
- (id)copyWithZone:(NSZone *)zone //NSCopying协议中的方法,需要实现
{
Person * p = [[[Person class] allocWithZone:zone] init];
[p setName:_name sex:_sex];
return p;
}
- (void)setName:(NSString *)name
sex:(NSString *)sex
{
_name = name;
_sex = sex;
}
@end
注意, - (id)copyWithZone:(NSZone *)zone是 NSCopying 协议中的方法,对于接受了该协议的自定义类,必须实现该方法.
另外,当 Person 类没有子类的时候,可以这样写:
Person * p = [[[Person class] allocWithZone:zone] init];
当有子类继承 Person 类的时候,自然也会继承- (id)copyWithZone:(NSZone )zone方法,此时如果仍然按照上面的语句(Person p = [[[Person class] allocWithZone:zone] init];)写,那么返回的将不是子类对象,而是一个 Person 类对象,为了安全起见,可以改为如下:
Person * p = [[[self class] allocWithZone:zone] init];
//或者
id p = [[[self class] allocWithZone:zone] init];
这样就能保证返回的是子类对象.如果编写一个类的copyWithZone:方法,而该类的超类也实现了协议,那么应该先调用超类的copy方法以复制继承来的实例变量,然后加入自己的代码以复制想要添加到该类中的任何附加的实例变量(如果有的话)。