您的位置:首页 > 移动开发 > Objective-C

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

2014-03-12 16:15 561 查看
@对于自定义对象的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);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐