关于数组深拷贝 initWithArray:copyItems:

作者: 童话镇里蜿蜒的河 | 来源:发表于2019-06-18 16:27 被阅读0次

    包含有对象类型的数组。无论可变还是不可变,通过copy,mutableCopy都不能将数组内的model完全copy一份,虽然得到的数组是新的,但数组中model的指针指向的还是之前的model。此时,如果改变了数组中model的值,原数组会受到影响。

        Person * a = [Person new];
        a.name = @"a";
        a.gender = @"male";
        
        Person * b = [Person new];
        b.name = @"b";
        b.gender =@"female";
        
        NSMutableArray *mutA = [NSMutableArray arrayWithObjects:a,b, nil];
        NSMutableArray *mutB = [mutA mutableCopy];
        
        Person *c = mutB.firstObject;
        c.name = @"c";
        c.gender = @"female";
    
    exOne.jpg

    如果对象是单层的(没有嵌套的模型),此时,model遵循NSCopying,NSMutableCopying协议,实现copyWithZone和mutableCopyWithZone方法。

    - (id)copyWithZone:(NSZone *)zone{
        Person *person = [[Person allocWithZone:zone] init];
        person.name = self.name;
        person.gender = self.gender;
        return person;
    }
    
    - (id)mutableCopyWithZone:(NSZone *)zone{
        Person *person = [[Person allocWithZone:zone] init];
        person.name = self.name;
        person.gender = self.gender;
        return person;
    }
    

    Array通过 initWithArray:copyItems: 方法可以得到一个完全拷贝过的数组(数组内的model也是全新的model)。

        NSMutableArray *mutB = [[NSMutableArray alloc] initWithArray:mutA copyItems:YES];
    
    exTwo.jpg

    但是!!

    如果数组内的model有嵌套,这个方法就不行了。

       @interface Person : NSObject
    
        @property (nonatomic, strong) NSString *name;
    
        @property (nonatomic, strong) Gender *gender;
    
        @end
    
        Person * a = [Person new];
        a.name = @"a";
        Gender *agender = [Gender new];
        agender.title = @"male";
        a.gender = agender;
        
        Person * b = [Person new];
        b.name = @"b";
        Gender *bgender = [Gender new];
        bgender.title =@"female";
        b.gender = bgender;
        
        NSMutableArray *mutA = [NSMutableArray arrayWithObjects:a,b, nil];
        NSMutableArray *mutB = [[NSMutableArray alloc] initWithArray:mutA copyItems:YES];
        
        Person *c = mutB.firstObject;
        c.name = @"c";
        c.gender.title = @"female";
    
    exThree.jpg

    可以看出,改动B数组中的firstObject,A中的name没有跟着改变,但A中的gender发生了变化。

    接下来再试一下,gender类也遵循NSCopying,NSMutableCopying协议。看下是什么效果。

    - (id)copyWithZone:(NSZone *)zone{
        Gender *gender = [[Gender allocWithZone:zone] init];
        gender.title = self.title;
        return gender;
    }
    
    - (id)mutableCopyWithZone:(NSZone *)zone{
        Gender *gender = [[Gender allocWithZone:zone] init];
        gender.title = self.title;
        return gender;
    }
    
    exFour.jpg

    如上图所示,依然不能满足要求。

    归档接归档。

    将A数组序列化为一个Data,再将Data解归档为一个新的数组。此时的数组就是一个全新的数组。

    person和gender类都需要遵循NSCoding协议,实现initWithCoder 和 encodeWithCoder方法。


    exSix.jpg

    再试一次, bingo!


    exFive.jpg

    相关文章

      网友评论

        本文标题:关于数组深拷贝 initWithArray:copyItems:

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