前言
只有遵守了NSCopying协议的类,才能使用copy语法(也即copy方法,通过一个对象,产生一个同类型的对象)。
自定义类如何实现copy语法?
(1)遵守NSCopying协议
遵守NSCopying协议(2)实现唯一的一个协议方法
实现协议方法重点是如何实现协议方法
(1)如果你想让外界这样调用:
Person *per = [[Person alloc]init];
per.name = @"chj";
per.sex = @"male";
per.age = 18;
Person *per2 = [per copy];
NSLog(@" %@,per = %p",per,per);
NSLog(@" %@,per2 = %p",per2,per2);
那就这样实现:
- (nonnull id)copyWithZone:(nullable NSZone *)zone {
Person *per = [[Person allocWithZone:zone]init];
per.name = self.name; 在当前对象内产生新对象并对其完成赋值
per.sex = self.sex;
per.age = self.age;
return per;
}
- (NSString *)description{
//提供输出方法,否则打印时只会对象打印地址
return [NSString stringWithFormat:@"name = %@,sex = %@,age = %zd",self.name,self.sex,self.age];
}
(2)如果你想让外界这样调用:
Person *person = [[Person alloc]initWithName:@"chj" sex:@"male" age:18];
Person *person2 = [person copy];
NSLog(@"person = %@,person = %p",person,person);
NSLog(@"person2 = %@,person2 = %p",person2,person2);
那就这样实现:
- (instancetype)initWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age{
self = [super init];
if (self) {
self.name = name;
self.sex = sex;
self.age = age;
}
return self;
}
- (nonnull id)copyWithZone:(nullable NSZone *)zone {
Person *person = [[Person allocWithZone:zone]initWithName:self.name sex:self.sex age:self.age];
return person;
}
总结:
(1)无论哪种实现方式,当【person copy】是都会调用copyWithZone:方法。所以,虽然协议方法不是@required修饰的,但必须实现该方法,要不然达不到【拷贝】对方的目的;
(2)copyWithZone:方法传进去的zone就是对象【拷贝】时有关对象的内存空间,必须要利用该内存区域,否者得不到对方的信息。所以alloc时走的是allocWithZone:方法,按照该内存空间的特有结构去分配新的存储空间;init初始化时,你可以先默认初始化,而后再分别赋值(只能在该方法中);也可以直接初始化(构造方法)
(3)自定类的description方法,默认时打印self,也即只有地址,无法打印详细信息,故最好重写该方法,自定义输出字符串,方便测试。
(4)对拷贝而来的新对象赋值时要知道self
代表的是什么,这样才能理解per.name = self.name;
的真正意义;
网友评论