美文网首页
NSCopying协议

NSCopying协议

作者: c048e8b8e3d7 | 来源:发表于2016-09-02 14:08 被阅读204次

    先来看一段代码

    NSMutableArray *arr1 = [[NSMutableArray alloc] initWithObjects:@1, @2, @3, nil];
    NSMutableArray *arr2 = arr1;
    [arr1 removeObjectAtIndex:0];
    

    在删除arr1第一个元素的同时,arr2的第一个元素也被删除了,这很好理解,因为两个对象都指向同一个地址
    如果想操作arr1的同时不影响到arr2,则只需改动一句

    NSMutableArray *arr2 = [arr1 copy];
    

    如果调用copy方法的对象是自己定义的对象,那么该对象需要实现NSCopying协议
    Person.h

    @interface Person : NSObject<NSCoding, NSCopying>
    
    @property(nonatomic, copy) NSString *name;
    @property(nonatomic, assign) NSInteger age;
    
    @end
    

    Person.m

    - (id)copyWithZone:(NSZone *)zone
    {
        Person *copy = [[[self class] alloc] init];
        
        copy.name = self.name;
        copy.age  = self.age;
        
        return copy;
    }
    

    更复杂的情况

    @interface Book : NSObject
    @property(nonatomic, copy) NSString *name;
    @property(nonatomic, assign) float price;
    @end
    
    @interface Person : NSObject<NSCopying>
    @property(nonatomic, copy) NSMutableString *name;
    @property(nonatomic, strong) Book *book;
    @end
    
    @implementation Person
    - (id)copyWithZone:(NSZone *)zone
    {
        Person *copy = [[[self class] alloc] init];
        copy.name = self.name;
        copy.book = self.book;
        return copy;
    }
    

    调用

    Book *book = [Book new];
    book.name = @"OBJC";
    book.price = 89.99;
    
    Person *p1 = [Person new];
    p1.name = [NSMutableString stringWithString:@"JC"];
    p1.book = book;
    
    Person *p2 = [p1 copy];
    
    [p2.name appendString:@"Henry"];//这里会报错(unrecognized selector)
    p2.book.name = @"JAVA";
    p2.book.price = 79.99;
    

    这里需要重点注意下,程序中p2.name明明定义的是NSMutableString类型,为什么会报不存在方法的错误呢?因为在合成gettersetter方法的时候没有提供mutableCopy指示符,因此即使定义实例变量时使用了可变类型,但只要使用copy指示符,实例变量实际得到的值总是不可变对象,系统默认的setter方法如下

    - (void)setName:(NSMutableString *)name
    {
        _name = [name copy];
    }
    

    因此需要在person.m文件中添加如下代码

    - (void)setName:(NSMutableString *)name
    {
        _name = [name mutableCopy];
    }
    

    p2.book任意属性变化也会影响到p1.book的属性
    这里需要修改两个地方

    1. Book类实现NSCopying协议
    2. Person.m- (id)copyWithZone:(NSZone *)zone方法中将copy.book = self.book;替换成copy.book = [self.book copy];

    相关文章

      网友评论

          本文标题:NSCopying协议

          本文链接:https://www.haomeiwen.com/subject/ifohettx.html