3

我正在使用 json-framework 从 JSON 响应中创建一个 NSDictionary。这么多效果很好。

现在,在这个 JSON 有效负载中有一个或多个对象 - 我们称它们为 X。在 XML 中有点像这样:

<OBJECTS>
  <X>
    ...
  </x>
  <X>
    ...
  </X>
  <X>
    ...
  </X>
</OBJECTS>

当我查看前面提到的所有 X 的 NSDictionary 对象时,如下所示:

NSDictionary *results = [[dict objectForKey:@"OBJECTS"] objectForKey:@"X"];

甚至:

NSDictionary *results = [dict valueForKeyPath:@"OBJECTS.X"];

根据 gdb,我得到一个 NSDictionary 对象的NSCFArray。(是的,我在这里也闻到了一些有趣的东西,但稍后会详细介绍。)

当只有一个名为 X 的对象时,我会返回一个诚实的 NSDictionary。

所以......我应该怎么做才能使其行为一致,无论有多少 X ?

乍一看,我认为我只是将 results 更改为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";
    };
}

欢迎/赞赏线索!您甚至可能会问是否有必要将其分开,但现在让我们假设这次旅行确实是必要的。(不过,如果有人对此感到足够强烈,我很高兴被说服。)

最终,在一天结束的时候,我想要一个 NSArray 的 NSDictionary 对象。

4

4 回答 4

2

我不熟悉 JSON 或 json 框架,但显然 objectForKey 不能用于访问 X,因为它们都具有相同的密钥。

如果您知道 objectForKey:@"OBJECTS" 将返回 NSDictionary(单个元素)或 NSDictionarys(多个 X 元素)的 NSArray,那么您可以执行以下操作:

if ( ![results isKindOfClass:[NSArray class]] ) {
    results =[NSArray arrayWithObject:results];
}

假设您完全了解 json 框架的行为方式,这将为您提供一致的结果。它会有些脆弱,如果元素返回一个条目数组而不是 NSDitionary,那么它就会全部崩溃。

json-framework 可能有一个配置设置,可让您控制它在这种情况下的行为方式,这将是可取的。

于 2009-06-22T06:12:57.817 回答
2
NSDictionary *results = [[dict objectForKey:@"OBJECTS"] objectForKey:@"X"];

NSDictionary *results = [dict valueForKeyPath:@"OBJECTS.X"];

上面两个是完全一样的。第一个操作比第二个操作成本高一点。

于 2010-02-24T18:40:12.930 回答
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)。

于 2009-06-22T14:07:29.950 回答
0

我不认为你的两个代码示例,

NSDictionary *results = [[dict objectForKey:@"OBJECTS"] objectForKey:@"X"];

NSDictionary *results = [dict valueForKeyPath:@"OBJECTS.X"];

是等价的。Key-Value-Coding 有一些额外的智能来处理集合,这可能会让你失望。(可以在 Scott Stevenson 的博文 Theocacao: NSArray and KVC中找到一个示例。)如果您恢复到前者,您可能会得到您期望的行为。

于 2009-06-22T20:29:22.077 回答