Objective-C Copy语法(二)对于我们自定义对象Copy以及[self class]相关的错误

@对于自定义对象的Copy:该类必须实现 NSCopying 协议,重写 copyWithZone 方法.

@对于自定义对象的mutableCopy:必须实现 NSMutableCopying协议,重写 utableCopyWithZone 方法。

看看下面的一个demo:

@interface Student : NSObject <NSCopying>

@property (nonatomic, copy) NSString *name;

+ (id)studentWithName:(NSString *)name;

@end

@implementation Student

+ (id)studentWithName:(NSString *)name {
    // 注:[self class]返回的是类,打印出来就相当于类名
    // 这里[Student alloc]最好写成[self class]

    Student * student = [[[[self class] alloc] init] autorelease];
    student.name = name;
    
    return student;
}

#pragma mark copying协议的方法 ------ 实现对象可变
- (id)copyWithZone:(NSZone *)zone {
    
    // (NSZone *)zone的含义就是为要建副本对象已经准备好了新开辟的内存空间
    // 所有copy出来的对象是一个新的对象,修改它的属性不会影响源对象
    // 这里[Student alloc]最好写成[self class]
    // 注:[self class]返回的是类,打印出来就相当于类名

    Student * copy = [[[self class] allocWithZone:zone] init];
    
    // 拷贝名字给副本对象
    copy.name = self.name;
    
    return copy;
}

#pragma mark copying协议的方法 ------ 实现对象不可变

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

    return self;
}
@end

main函数:
#pragma mark 演示Student的copy
void studentCopy() {
    Student * student1 = [Student studentWithName:@"student1"];
    
    Student * student2 = [student1 copy];
    student2.name = @"student2";
    
    NSLog(@"student1:%@", student1);
    NSLog(@"student2:%@", student2);
    
}


@ 为什么我一再强调要写成[self class],下面我们通过让一个子类继承Student,来说明这个问题,顺便也来实现一下子类      继承父类后,如何实现copy(如果某一个子类继承了实现了NSCopying协议的基类,那么该子类也是会自动继承这        个协议的方法,但是需要自己重新实现。)

@interface StupidStudent : Student

@property (nonatomic, assign) int age;


+ (id)stupidStudentWithAge:(int)age name:(NSString *)name;

+ (id)study;
@end

@implementation StupidStudent

+ (id)stupidStudentWithAge:(int)age name:(NSString *)name {
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    // 如果父类Student的初始化那里写成[Student alloc],子类 StupidStudent创建对象利用super指示器去到父类中调用        父类的studentWithName的方法,创建的会是一个父类Student对象,而并不是StupidStudent对象,父类中并不存在          age属性和+ (id)study方法,你拿父类的实例对象去调用不存在的属性和方法,程序就直接报错了
    StupidStudent * stupid = [super studentWithName:name];
    
    stupid.age = age;
    
    return stupid;
}

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


    // 一定要调用父类的方法
    GoodStudent * copy = [super copyWithZone:zone];
    
    copy.age = self.age;
    
    return copy;
}
@end

main函数:
void goodStudentCopy() {
    StupidStudent * student1 = [StupidStudent stupidStudentWithAge:10 name:@"stupid1"];
    
    StupidStudent * student2 = [student1 copy];
    student2.name = @"stupid2";
    student2.age = 11;
    
    NSLog(@"student1:%@", student1);
    NSLog(@"student2:%@", student2);
}


你可能感兴趣的:(copy,Objective-C,Class,self)