iOS 对象数组的深拷贝(NSCoding协议)

项目过程中遇到了对象数组的使用:联系人界面——需要分区显示,如果我存放在一个数组然后每次显示都重新分组发现会有一个计算的延迟,所有我先进行分区放在了一个单例类中的字典中。当我需要用到这个联系人的界面额外定义一个NSDictionary对它赋值,试图修改NSDictionary时发现存放在单例类中的数组对象也被修改了。感觉很无语啊。当时我的嵌套是这样的

NSDictionary@{key1:NSMutableArray@[对象1,对象2],key2:NSMutableArray@[对象3,对象4],...}

就是在一个单例类中定义了一个不可变字典NSDictionary的属性,存放了n个可变数组NSMutableArray,而这些可变数组可以动态增加或者删除数组内存放的对象。

在网上看了很多对象的深拷贝,浅拷贝copy/mutableCopy。并且我已经实现了NSCoding协议。可是发现全部无效。于是我写了一个Test工程发现一个问题

 NSArray *array1 = [NSArray arrayWithObjects:@"a", nil];

 NSMutableArray *arry2 = [array1 mutableCopy];

 [arry2 replaceObjectAtIndex:0 withObject:@"b"];

 NSLog(@"%@",array1);

这样输出结果依然是@[a]

但是当我定义两个一个实现了NSCoding协议并且有一个name属性的Person对象并且放到数组中时

Person *person1 = [[Person alloc] init];
    person1.name = @"a";

    NSArray *array1 = [NSArray arrayWithObjects:person1, nil];

    NSArray *arry2 = [NSArray arrayWithArray:array1];

    [arry2 enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        Person *person = obj;
        person.name = @"c";
    }];

    NSLog(@"%@",array1);

输出结果Person的name却是c
有人说如果要想深拷贝数组中的对象就必须重新建立一个数组,然后在循环的时候给新数组即:

Person *person1 = [[Person alloc] init];
    person1.name = @"a";

    NSArray *array1 = [NSArray arrayWithObjects:person1, nil];

    NSMutableArray *arrayM = [NSMutableArray arrayWithCapacity:0];
    [array1 enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        Person *person = [obj copy];
        person.name = @"c";
        [arrayM addObject:person];
    }];

    NSLog(@"%@",array1);

并且遍历的时候对象必须copy,不然还是难以达到深拷贝。
后来找到另一种方法,就是通过[NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:]];

Person *person1 = [[Person alloc] init];
    person1.name = @"a";

    Person *person2 = [[Person alloc] init];
    person2.name = @"b";

    NSArray *array1 = [NSArray arrayWithObjects:person1, nil];

    NSArray *array2 = [NSArray arrayWithObjects:person2, nil];

    NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:array1,@"a",array2,@"b", nil];

    [Object shareObject].dict = dict;

    NSLog(@"1:%@",[Object shareObject].dict);

    NSDictionary *temDict = [[Object shareObject].dict mutableCopy];

    NSMutableArray *arrayM = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:[temDict objectForKey:@"a"]]];

    [arrayM enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        Person *person = obj;
        person.name = @"c";
    }];

    NSLog(@"2:%@",[Object shareObject].dict);

并且不管你嵌套了多少层,只要每一层都实现了NSCoding协议也可以实现深拷贝。后来我就放弃了把联系人放在单例类中,直接放在了本地文件中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值