objective-c - NSJSONSerialization 不创建可变容器

标签 objective-c ios json

代码如下:

NSError *parseError;
NSMutableArray *listOfObjects = [NSJSONSerialization JSONObjectWithData:[@"[]" dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&parseError];
NSLog(@"Is mutable? %li", [listOfObjects isKindOfClass:[NSMutableArray class]]);

listOfObjects = [NSJSONSerialization JSONObjectWithData:[@"[[],{}]" dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&parseError];
NSLog(@"Is mutable? %li", [listOfObjects isKindOfClass:[NSMutableArray class]]);

如您所见,我两次调用完全相同的方法来解析 JSON,一次是在 JSON 中包含一个空列表,然后是一个包含对象的列表。结果如下:

Is mutable? 0
Is mutable? 1 

问题是 NSJSONSerialization 似乎没有遵循为空列表创建可变容器的选项。对我来说似乎是个错误,但也许我只是误解了一些事情。

有什么想法吗?

最佳答案

这正如预期的那样工作:

NSString *s = @"{ \"objs\": [ \"a\", \"b\" ] }";    
NSData *d = [NSData dataWithBytes:[s UTF8String] length:[s length]];
id dict = [NSJSONSerialization JSONObjectWithData:d options:NSJSONReadingMutableContainers error:NULL];

NSLog(@"%@", dict);

[[dict objectForKey:@"objs"] addObject:@"c"];

NSLog(@"%@", dict);
NSLog(@"%@", [[dict objectForKey:@"objs"] class]);

这是控制台输出:

2012-03-28 13:49:46.224 ExampleRunner[42526:707] {
    objs =     (
        a,
        b
    );
}
2012-03-28 13:49:46.225 ExampleRunner[42526:707] {
    objs =     (
        a,
        b,
        c
    );
}
2012-03-28 13:49:46.225 ExampleRunner[42526:707] __NSArrayM

编辑

请注意,如果我们将以下行附加到上面的代码...

NSLog(@"%@", [[dict objectForKey:@"objs"] superclass]);

...我们在控制台上得到以下输出:

2012-03-28 18:09:53.770 ExampleRunner[42830:707] NSMutableArray

...以防万一不清楚 __NSArrayMNSMutableArray 的私有(private)子类,从而证明 OP 的代码确实按预期工作(除了对于他的 NSLog 声明)。

编辑

哦,顺便说一句,下面这行代码...

NSLog(@"%d", [[dict objectForKey:@"objs"] isKindOfClass:[NSMutableArray class]]);

...导致以下控制台输出:

2012-03-28 18:19:19.721 ExampleRunner[42886:707] 1

编辑(响应更改的问题)

有趣...看起来像一个错误。给定以下代码:

NSData *dictData2 = [@"{ \"foo\": \"bar\" }" dataUsingEncoding:NSUTF8StringEncoding];
id dict2 = [NSJSONSerialization JSONObjectWithData:dictData2 options:NSJSONReadingMutableContainers error:NULL];
NSLog(@"%@", [dict2 class]);
NSLog(@"%@", [dict2 superclass]);
NSLog(@"%d", [dict2 isKindOfClass:[NSMutableDictionary class]]);

// This works...
[dict2 setObject:@"quux" forKey:@"baz"];
NSLog(@"%@", dict2);

NSData *dictData = [@"{}" dataUsingEncoding:NSUTF8StringEncoding];
id emptyDict = [NSJSONSerialization JSONObjectWithData:dictData options:NSJSONReadingMutableContainers error:NULL];
NSLog(@"%@", [emptyDict class]);
NSLog(@"%@", [emptyDict superclass]);
NSLog(@"%d", [emptyDict isKindOfClass:[NSMutableDictionary class]]);

//...but this fails:
[emptyDict setObject:@"quux" forKey:@"baz"];
NSLog(@"%@", emptyDict);

这是控制台输出:

2012-03-29 09:40:52.781 ExampleRunner[43816:707] NSMutableDictionary
2012-03-29 09:40:52.782 ExampleRunner[43816:707] 1
2012-03-29 09:40:52.782 ExampleRunner[43816:707] __NSCFDictionary
2012-03-29 09:40:52.782 ExampleRunner[43816:707] NSMutableDictionary
2012-03-29 09:40:52.783 ExampleRunner[43816:707] 1
2012-03-29 09:40:52.783 ExampleRunner[43816:707] {
    baz = quux;
    foo = bar;
}
2012-03-29 09:40:52.784 ExampleRunner[43816:707] __NSCFDictionary
2012-03-29 09:40:52.784 ExampleRunner[43816:707] NSMutableDictionary
2012-03-29 09:40:52.784 ExampleRunner[43816:707] 1
2012-03-29 09:40:52.785 ExampleRunner[43816:707] NSException: -[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object

因此以这种方式创建的空数组和字典似乎没有按预期运行。

关于objective-c - NSJSONSerialization 不创建可变容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9912707/

相关文章:

iphone - 以编程方式更改 UISlider 的范围

ios - 在 iOS 上将数据保存到磁盘

ios - 二进制表达式 ('BOOL'(又名 'signed char')和 'void' 的无效操作数)

android - 使用 jackson 解析 Realm 模型

javascript - Node.js : xml-js (npm ver 1. 6.4)

ios - 具有非唯一部分名称的 NSFetchedResultsController

objective-c - 并非所有值对象都可以使用 XCode Watch 和 Debug 控制台查看

objective-c - 将 swift 的 "forced downcast(as!)"转换为 objective-c

iOS - 使用 Facebook 登录但仍然收到 : “Unauthenticated access is not supported for this identity pool”

mysql - mySQL 之后无法从 JSON 获取值