json NSDictionary objectForKey 返回值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1025389/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:17:05  来源:igfitidea点击:

NSDictionary objectForKey return value

objective-cjsonparsingnsarraynsdictionary

提问by Joe D'Andrea

I'm using json-framework to create a NSDictionary out of a JSON response. That much works wonderfully.

我正在使用 json-framework 从 JSON 响应中创建一个 NSDictionary。这非常有效。

Now, within this JSON payload are one or more objects - let's call them X. Sort of like this in XML:

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

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

When I look in the aforementioned NSDictionary object for all Xs, like so:

当我查看所有 X 的上述 NSDictionary 对象时,如下所示:

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

Or even:

甚至:

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

I get, according to gdb, a NSCFArrayof NSDictionary objects. (Yes, I smell something funny here too, but more on this in a moment.)

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

When there is only oneobject named X, I get back an honest-to-goodness NSDictionary.

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

So ... what should I do to make this behave consistently, no matter how many Xs there are?

所以......无论有多少X,我应该怎么做才能使这种行为始终如一?

At first glance, I'd think I just change results to be NSArray *, but what happens when I want to fast enumerate over the results? Right now I do this:

乍一看,我认为我只是将结果更改为NSArray *,但是当我想快速枚举结果时会发生什么?现在我这样做:

for (NSDictionary *result in results)

In the NSCFArray case (multiple Xs), I get back an individual NSDictionary for each X. In the single X case, I get back the one NSDictionary, except now my perspective is one level too deep. In other words, instead of this (contrived example):

在 NSCFArray 情况下(多个 X),我为每个 X 取回一个单独的 NSDictionary。在单个 X 情况下,我取回一个 NSDictionary,但现在我的观点太深了一层。换句话说,而不是这个(人为的例子):

(gdb) po results
<NSCFArray 0xd4a940>(
{
    foo =     {
        bar = "something";
    };
}
{
    foo =     {
        bar = "something else";
    };
}
)

I get this:

我明白了:

(gdb) po results
{
    foo =     {
        bar = "something";
    };
}

Clues welcome/appreciated! You may even ask if it's necessary to have to break this apart at all, but for now let's suppose this trip is really necessary. (Still, I'm happy to be persuaded otherwise, if someone feels strongly enough about it.)

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

Ultimately, at the end of the day, I want to have a NSArray of NSDictionary objects.

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

采纳答案by Peter N Lewis

I am not familiar with JSON or the json-framework, but clearly objectForKey cannot be used to access the X's since they all have the same key.

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

If you know that objectForKey:@"OBJECTS" will return either an NSDictionary (single element) or an NSArray of NSDictionarys (multiple X elements), then you could do something like:

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

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

That will get you a consistent result, assuming you understand exactly how the json-framework will behave. It will be somewhat fragile, if the elements ever return an array of entries instead of an NSDitionary then it will all fall apart.

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

There may be a configuration setting for the json-framework that lets you control how it behaves in this case and that would be preferable.

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

回答by prav

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

and

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

The above two are exactly same. The first operation is a little costlier operation than the second one.

以上两个完全一样。第一个操作比第二个操作稍微贵一点。

回答by Joe D'Andrea

Here's what I ended up doing:

这是我最终做的:

// 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;
}

It's worth pointing out that JSONValuecan also return a dictionary oran array. However, I'm looking inside the dictionary post-assignment (OBJECTS.X).

值得指出的是JSONValue也可以返回字典数组。但是,我正在查看分配后的字典(OBJECTS.X)。

回答by Stig Brautaset

I don't think your two code examples,

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

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

and

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

are equivalent. Key-Value-Coding has some extra smarts to work with collections, which might be throwing you off here. (An example can be found in the blog post Theocacao: NSArray and KVCby Scott Stevenson.) If you revert back to the former you might get the behaviour you expect.

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