【问题标题】:NSArray handled as NSDictionaryNSArray 作为 NSDictionary 处理
【发布时间】:2014-05-08 18:28:29
【问题描述】:

我正在通过 Objective-c 应用程序对我的 Web 服务器进行 HTTP 调用。服务器返回的 json 通常如下所示:

{
  "name": "test",
  "surname": "test",
}

但有时,当我请求某项列表时,我会得到如下 JSON:

[
  { "name": "test" },
  { "name": "test" },
]

现在,我以这种方式将返回的对象作为 NSDictionary 处理:

NSDictionary *results = [http doRequestWithData:@{ @"tag": @"whatever" } atUrl:@"/search"]
NSLog(@"%@", results);

为简单起见,我省略了 doRequestWithData 的实现,因为其中有趣的部分是,当我执行数据的 NSLog 时,我得到以下信息:

(
        {
        "_id" = 5353c332339a5ea32e000008;
        content = "i am the first search result";
    },
        {
        "_id" = 5353c32b339a5ea32e000007;
        content = "I am the second";
    },
        {
        "_id" = 5353c31c339a5ea32e000006;
        content = "third";
    },
)

谁能解释这是怎么发生的?返回的数据是一个 NSDictionary,但从控制台看它就像一个数组,因为我看不到键!


更新:我在我的 http 类中使用 NSJSONSerialization 来序列化对象。文档说它可能会根据数据返回一个字典或一个数组。但问题是我明确将其定义为 NSDictionary!这至少不应该抛出和错误吗? 这是我在我的 http 类中用来定义返回的 nsdictionary 的:

NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
return responseDict;

【问题讨论】:

  • 你能确认 NSJSONSerialization 正在返回 NSDicationary 类的数据吗? NSLog(@"%@", [data class]);
  • 好吧,上面写着 __NSCFArray。这解释了很多,但我仍然不明白为什么它工作得如此完美?类型明确定义为 NSDictionary!

标签: objective-c json


【解决方案1】:

与 Java(和类似语言)不同,Obj-C 中没有运行时类型检查。

如果你的方法返回一个NSArray 并且你将它存储到一个NSDictionary 中,这对Obj-C 来说不是问题。直到您尝试调用未为 NSArray 定义的方法(例如 objectForKey:)。

通常,这些问题应该在编译时就解决

+[NSJSONSerialization JSONObjectWithData:...] 返回一个id(它可以返回NSArrayNSDictionary)并且id 与任何类型兼容。

【讨论】:

  • 您认为返回 id 类型的对象会更好吗?而不是数组或字典
  • @user3060636 如果两者都可能为您返回值,那么id 会更好。
【解决方案2】:

最好的办法是使用isKindOfClass: 对返回值进行自己的类型检查。

NSData *data = ...;

NSError *__autoreleasing jsonError;
NSDictionary *dictionary = data ? [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError] : nil;

if (jsonError || ![dictionary isKindOfClass:[NSDictionary class]])
    dictionary = nil;

您可能想要做更多的处理,但这至少可以确保您永远不会访问错误的对象类型。

【讨论】:

    猜你喜欢
    • 2010-11-27
    • 2013-03-10
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-26
    • 1970-01-01
    相关资源
    最近更新 更多