深度可变的seralizing iOS词典/数组

时间:2012-04-28 16:03:40

标签: ios json ios5 nsmutablearray

某些jSON来自我的应用分解的本地文件:{"1":{"name":"My List","list":[]}}

由于使用了以下选项,我使用这个iOS 5.1代码将整个内容转换为我认为是可变字典的内容:

NSData *data = [[NSFileManager defaultManager] contentsAtPath:jSONFile];
NSMutableDictionary *mydict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves error:&error];

给定选项NSJSONReadingMutableContainers我会假设子数组list属于这个类:“NSJSONReadingMutableContainers - 指定将数组和字典创建为可变对象。”来自NSJSONSerialization Class Reference,但是当我尝试执行以下代码时:

NSMutableArray *myarray = [mydict objectForKey:@"1"] objectForKey:@"list"];
[myarray addObject:@"test"];

执行在第二行(addObject)上爆炸,但有以下例外:

- [__ NSArrayI addObject:]:无法识别的选择器发送到实例0x887e840

**由于未捕获的异常'NSInvalidArgumentException'终止应用程序,原因:' - [__ NSArrayI addObject:]:无法识别的选择器发送到实例0x887e840'

从我的SO研究(123),似乎上述错误通常是在对象尝试的元素(字典/数组)时引起的要添加到可变。此外,从我的SO研究(12)来看,似乎没有办法测试对象在obj-c中是否确实是可变的,这是设计的。

所以我想我的问题是,如何确保我的jSON结构在序列化之后(或之后)确实是“深度”可变的?我知道我无法在mutableCopy上使用mydict,因为该功能很浅。任何方向/解决方案将不胜感激。谢谢。

2 个答案:

答案 0 :(得分:2)

我使用过这个实现,它使用nsdictionary上的一个类别来做一个可变的深层复制并且工作得很好:

deep mutable copy of a NSMutableDictionary

因此,在对json进行反序列化后,您可以在其上调用mutableDeepCopy。

这就是我所拥有的:

@interface NSDictionary(Category)
- (NSMutableDictionary *)mutableDeepCopy;
@end

@implementation NSDictionary(Category)
- (NSMutableDictionary *)mutableDeepCopy{
    NSMutableDictionary * ret = [[NSMutableDictionary alloc]
                             initWithCapacity:[self count]];

   NSMutableArray * array;

   for (NSString* key in [self allKeys]){

       if([[self objectForKey:key] respondsToSelector:@selector(mutableCopyWithZone:)]){
            array = [(NSArray *)[self objectForKey:key] mutableCopy];
           [ret setValue:array forKey:key];
       }
       else{
            [ret setValue:[self objectForKey:key] forKey:key];

       }
    }

    return ret;
}

@end

答案 1 :(得分:0)

Apple有一个解决方案:

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/PropertyLists/ReadWritePlistData/ReadWritePlistData.html

"此调用产生一个可变数组,每个元素中都有可变字典。每个字典中的每个键和每个值本身也是可变的。"