我正在使用json-framework从JSON响应中创建NSDictionary。这非常有效。
现在,在这个JSON有效负载中有一个或多个对象 - 让我们称它们为X.在XML中这样排序:
<OBJECTS>
<X>
...
</x>
<X>
...
</X>
<X>
...
</X>
</OBJECTS>
当我查看上述NSDictionary对象中的所有X时,如下所示:
NSDictionary *results = [[dict objectForKey:@"OBJECTS"] objectForKey:@"X"];
甚至:
NSDictionary *results = [dict valueForKeyPath:@"OBJECTS.X"];
根据gdb,我得到了NSDictionary对象的 NSCFArray 。 (是的,我在这里也闻到了一些有趣的东西,但稍后会对此有所了解。)
当只有一个对象名为X时,我会回到一个诚实的NSDictionary。
那么......无论X有多少X,我该怎么做才能使这种行为始终如一?
乍一看,我认为我只是将结果更改为 NSArray * ,但是当我想快速枚举结果时会发生什么?现在我这样做:
for (NSDictionary *result in results)
在NSCFArray的情况下(多个X),我为每个X取回一个单独的NSDictionary。在单个X的情况下,我找回一个NSDictionary,除了现在我的观点是一个级别太深。换句话说,而不是这个(人为的例子):
(gdb) po results
<NSCFArray 0xd4a940>(
{
foo = {
bar = "something";
};
}
{
foo = {
bar = "something else";
};
}
)
我明白了:
(gdb) po results
{
foo = {
bar = "something";
};
}
线索欢迎/赞赏!你甚至可能会问是否有必要完全打破这一点,但是现在让我们假设这次旅行真的是必要的。 (尽管如此,如果有人对此感到非常满意,我很高兴能被说服。)
最终,在一天结束时,我想要一个NSD阵列的NSD阵列对象。
答案 0 :(得分:2)
NSDictionary *results = [[dict objectForKey:@"OBJECTS"] objectForKey:@"X"];
和
NSDictionary *results = [dict valueForKeyPath:@"OBJECTS.X"];
以上两者完全相同。第一次操作比第二次操作稍贵一些。
答案 1 :(得分:1)
我不熟悉JSON或json框架,但很明显objectForKey不能用来访问X,因为它们都有相同的密钥。
如果您知道objectForKey:@“OBJECTS”将返回NSDictionary(单个元素)或NSDictionarys的NSArray(多个X元素),那么您可以执行以下操作:
if ( ![results isKindOfClass:[NSArray class]] ) {
results =[NSArray arrayWithObject:results];
}
假设您完全了解json框架的行为方式,那将为您提供一致的结果。它会有些脆弱,如果元素返回一个条目数组而不是NSDitionary那么它将全部崩溃。
json-framework可能有一个配置设置,可以让你控制它在这种情况下的行为,这是更好的选择。
答案 2 :(得分:0)
这是我最终做的事情:
// Get the JSON response and return the result:
NSString *jsonString = [NSString stringWithContentsOfURL:url];
NSDictionary *dict = [jsonString JSONValue];
// If OBJECTS.X gets a dictionary (one value), make an array of one.
id myObject = [dict valueForKeyPath:@"OBJECTS.X"];
if ([myObject isKindOfClass:[NSDictionary class]]) {
results = [NSArray arrayWithObject:myObject];
} else {
results = myObject;
}
值得指出的是,JSONValue也可以返回字典或数组。但是,我正在查找分配后的字典(OBJECTS.X)。
答案 3 :(得分:0)
我不认为你的两个代码示例,
NSDictionary *results = [[dict objectForKey:@"OBJECTS"] objectForKey:@"X"];
和
NSDictionary *results = [dict valueForKeyPath:@"OBJECTS.X"];
是等价的。 Key-Value-Coding有一些额外的智能来处理集合,这可能会让你失望。 (斯科特史蒂文森在博客文章Theocacao: NSArray and KVC中可以找到一个例子。) 如果你恢复到前者,你可能会得到你期望的行为。