美文网首页
model、array多层嵌套的深copy

model、array多层嵌套的深copy

作者: 114105lijia | 来源:发表于2020-02-06 16:00 被阅读0次

之前碰到一个需求,model和array多层嵌套,需要深copy。如下图结构:


image.png

看到需求后,第一反应就是

NSMutableArray *copyArray = [self.dataArray mutableCopy];

当我查看地址时,发现地址相同:(都是第一个元素的地址)


image.png

然后我想到的是,在model里面实现copy、mutablecopy协议,之后查看数组地址,还是相同。
当我mutablecopy数组里面的model时,2个model的地址确实不同,但是model里面的数组的地址又相同了。如下图:


image.png

之后想的是用归档和反归档:

- (void)archiverCopy {
    NSString *filePath = [NSHomeDirectory() stringByAppendingString:@"person.plist"];
    
    //归档 ios (2.0,12.0)
    BOOL success = [NSKeyedArchiver archiveRootObject:self.dataArray toFile:filePath];
    
    NSLog(@"%d",success);
    
    // 反归档
    NSMutableArray *copyArray = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
    NSLog(@"%@",copyArray);
}

最后查看地址,确实能实现model和array里面的每个元素都深copy,不过archiveRootObject方法只到iOS 12.0,之后需要使用archivedDataWithRootObject,即下面的方法:

- (void)archiverToCopy {
    
    //归档
    NSString *path = NSHomeDirectory();
    path = [path stringByAppendingString:@"Singel.plist"];
    //2:准备存储数据对象(用可变数组进行接收)
    NSMutableData *data = [NSMutableData new];
    //3:创建归档对象
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
    //4:开始归档
    [archiver encodeObject:self.dataArray forKey:@"cate"];
    //5:完成归档
    [archiver finishEncoding];
    //6:写入文件
    BOOL result = [data writeToFile:path atomically:YES];
    if (result) {
        NSLog(@"归档成功:%@",path);
    }
    
    //反归档
    //1:获取解档路径
    NSData *MyData = [NSData dataWithContentsOfFile:path];
    //2:创建反归档对象
    NSKeyedUnarchiver  *unarchiver= [[NSKeyedUnarchiver alloc]initForReadingWithData:MyData];
    //3:反归档
//    BigCateMode *bigModel = [BigCateMode new];
    NSMutableArray *archiverDataArray = [NSMutableArray array];
    archiverDataArray = [unarchiver decodeObjectForKey:@"cate"];
    //4:结束归档
    [unarchiver finishDecoding];
}

注意:使用归档和反归档时,model里面要实现encodeWithCoder和initWithCoder方法,不然会闪退。如下:

-(void)encodeWithCoder:(NSCoder *)aCoder{
    //对实例变量 进行归档
    [aCoder encodeObject:_bigCateName forKey:@"bigCateName"];
    [aCoder encodeObject:_bigCateCode forKey:@"bigCateCode"];
    [aCoder encodeObject:_bigCatelist forKey:@"bigCatelist"];
}

-(id)initWithCoder:(NSCoder *)aDecoder{
    if ([super init]) {
        self.bigCateName =[aDecoder decodeObjectForKey:@"bigCateName"];
        self.bigCateCode = [aDecoder decodeObjectForKey:@"bigCateCode"];
        self.bigCatelist = [aDecoder decodeObjectForKey:@"bigCatelist"];
    }
    return self;
}

使用归档和反归档,虽然可以实现深copy,但实现时,里面的每个model都需要实现归档和反归档方法,总感觉太麻烦。

其实要达到深copy的目的,就是把数组里面的每个元素,包括元素里面的对象或数组重新生成一个,自己一个一个的写,肯定嫌麻烦,不过利用runtime却可以一劳永逸。

我也偷个懒,直接用第三方框架MJExtension里面的方法,先将model转化为dictionary,然后转化成model。达到深copy的目的。如下:

//mjextension 实现深copy   注意要在.m文件中实现数组和model的映射
    NSDictionary *dic = [bigModel mj_keyValues];
    BigCateMode *mjCopyModel = [BigCateMode mj_objectWithKeyValues:dic];

demo

相关文章

  • model、array多层嵌套的深copy

    之前碰到一个需求,model和array多层嵌套,需要深copy。如下图结构: 看到需求后,第一反应就是 当我查看...

  • 每日一题

    20170830 数组扁平化: 实现一个flatten函数,将一个嵌套多层的数组 array(数组) (嵌套可以是...

  • js习题练习

    效果,实现代码reduce效果 效果实现一个flatten函数,将一个嵌套多层的数组 array(数组) (嵌套可...

  • flatten,map,reduce方法总结

    (1)flatten的用法 将一个嵌套多层的数组 array(数组) (嵌套可以是任何层数)转换为只有一层的数组,...

  • JavaScript编程---数组嵌套转单数组

    实现一个flatten函数,将一个嵌套多层的数组 array(数组) (嵌套可以是任何层数)转换为只有一层的数组,...

  • 『JavaScript专题』之数组扁平化

    JavaScript专题之数组扁平化 扁平化 数组的扁平化,就是将一个嵌套多层的数组 array (嵌套可以是任何...

  • python 深拷贝和浅拷贝

    浅拷贝 深拷贝 列表嵌套列表 里面的引用也会开辟新的内存去存储 深拷贝里面的列表都被拷出来。 copy.copy ...

  • js数组扁平化

    扁平化 数组的扁平化,就是将一个嵌套多层的数组 array (嵌套可以是任何层数)转换为只有一层的数组。 递归 e...

  • js实现数组扁平化

    js实现数组扁平化 数组的扁平化,就是将一个嵌套多层的数组array(嵌套可以是任何层数)转换为只有一层的额数组。...

  • model和数据的结合

    1,如果是只有一个model的话 2.如果是Model中嵌套model 的话 这是model中嵌套model的写法

网友评论

      本文标题:model、array多层嵌套的深copy

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