0

我很难从声明为的多级数组中提取字典:

NSArray *menuItems;看起来像这样:

Table =     (
                {
            MENUDESC = "HOME           ";
            MENUID = 1072;
            NAVIGATETO = "content.aspx?item=1072&pid=0";
            NAVIGATETO2 = "default.aspx?item=1072&pid=0";
            PARENTMENUID = "<null>";
            PROTECTED = "<null>";
            parentmenuid2 = "<null>";
        },
                {
            MENUDESC = "PRODUCTS &amp; SERVICES";
            MENUID = 1073;
            NAVIGATETO = "#";
            NAVIGATETO2 = "default.aspx?item=1073&pid=0";
            PARENTMENUID = "<null>";
            PROTECTED = "<null>";
            parentmenuid2 = "<null>";
        },
                {
            MENUDESC = "ABOUT US";
            MENUID = 1074;
            NAVIGATETO = "content.aspx?item=1074&pid=0";
            NAVIGATETO2 = "default.aspx?item=1074&pid=0";
            PARENTMENUID = "<null>";
            PROTECTED = "<null>";
            parentmenuid2 = "<null>";
        },
                {
            MENUDESC = "WHAT SETS US APART";
            MENUID = 1075;
            NAVIGATETO = "content.aspx?item=1075&pid=0";
            NAVIGATETO2 = "default.aspx?item=1075&pid=0";
            PARENTMENUID = "<null>";
            PROTECTED = "<null>";
            parentmenuid2 = "<null>";
        },
                {
            MENUDESC = "CASE STUDIES";
            MENUID = 1126;
            NAVIGATETO = "content.aspx?item=1126&pid=0";
            NAVIGATETO2 = "default.aspx?item=1126&pid=0";
            PARENTMENUID = "<null>";
            PROTECTED = "<null>";
            parentmenuid2 = "<null>";
        },
                {
            MENUDESC = "REQUEST PROPOSAL";
            MENUID = 1076;
            NAVIGATETO = "content.aspx?item=1076&pid=0";
            NAVIGATETO2 = "default.aspx?item=1076&pid=0";
            PARENTMENUID = "<null>";
            PROTECTED = "<null>";
            parentmenuid2 = "<null>";
        },
                {
            MENUDESC = CONTACT;
            MENUID = 1077;
            NAVIGATETO = "contactus.aspx?item=1077&pid=0";
            NAVIGATETO2 = "contactus.aspx?item=1077&pid=0";
            PARENTMENUID = "<null>";
            PROTECTED = "<null>";
            parentmenuid2 = "<null>";
        }
    );
}

从 JSON 创建,如下所示:

{
  "Table": [
    {
      "MENUID": 1072.0,
      "MENUDESC": "HOME           ",
      "PARENTMENUID": null,
      "NAVIGATETO": "content.aspx?item=1072&pid=0",
      "NAVIGATETO2": "default.aspx?item=1072&pid=0",
      "PROTECTED": null,
      "parentmenuid2": null
    },
    {
      "MENUID": 1073.0,
      "MENUDESC": "PRODUCTS &amp; SERVICES",
      "PARENTMENUID": null,
      "NAVIGATETO": "#",
      "NAVIGATETO2": "default.aspx?item=1073&pid=0",
      "PROTECTED": null,
      "parentmenuid2": null
    },
    {
      "MENUID": 1074.0,
      "MENUDESC": "ABOUT US",
      "PARENTMENUID": null,
      "NAVIGATETO": "content.aspx?item=1074&pid=0",
      "NAVIGATETO2": "default.aspx?item=1074&pid=0",
      "PROTECTED": null,
      "parentmenuid2": null
    },
    {
      "MENUID": 1075.0,
      "MENUDESC": "WHAT SETS US APART",
      "PARENTMENUID": null,
      "NAVIGATETO": "content.aspx?item=1075&pid=0",
      "NAVIGATETO2": "default.aspx?item=1075&pid=0",
      "PROTECTED": null,
      "parentmenuid2": null
    },
]
}

我正在研究示例代码,他们使用它来提取字典:

NSDictionary *items = [menuItems objectAtIndex:indexPath.row];

但这不起作用 - 我收到错误“发送的选择器无效”。我尝试了各种方法来访问数组中的数据。但是我发现的所有研究和答案都没有帮助。

我需要像这样创建 NSStrings:

NSString *text = [[menuItems objectForKey:@"Table"] objectForKey:@"MENUDESC"];
NSString *name = [[menuItems objectForKey:@"Table"] objectForKey:@"MENUID"];
4

4 回答 4

2

Objective-C 是一种相当动态的语言,因此即使您已menuItems声明为NSArray,也无法保证其在运行时的类型。如果您从问题中反序列化 JSON 对象并将其分配给menuItems,则实际上是在为它分配一个NSDictionary实例。请注意,JSON 的最外层符号是花括号,表示一个对象(转换为NSDictionary),而不是方括号,表示一个数组。这个对象有一个键,Table,一个数组作为关联值。

所以你需要做的是这样的:

NSArray *menuItems = JSONObject[@"Table"];

JSONObject您当前分配的内容在哪里menuItems。之后,menuItems指向一个字典数组,每个字典都应该能够为您提供所需的字符串。

于 2013-03-01T08:29:52.347 回答
1

也就是说,通过 JSON 字符串发送给您的内容。它以包含在 {} 中的键值对开始。它只有一个条目。该条目的键是“table”,它的值是一个包含多个对象的数组。数组的对象包含在 [] 中。数组中包含一组键/值对(包含在 {} 中)。

所以每个 {} 都会被转换成一个 NSDictionary,它是键值对的合适容器。并且每个 [],甚至是空的,都将被转换为对象的 NSArray。

你永远无法确定你收到了什么。因此,您应该始终仔细检查接收到的值是否是 NSArray、NSDictionary、NSString 或 NSNumber。(坦率地说,我不确定 NSDate。)通过使用(示例)来做到这一点

if ([myCurrentObject isKindOfClass[NSString class]]) {
  // process the data
} else {
  // react to the error because you were expecting a string and got something else
}

通过这样做,您可以让您的应用程序有机会做出正确反应,即使它无法处理数据。这比您当前观察到的由未捕获的异常引起的中止要好得多。

准备好接收空数组和字典。对于字典来说,这并不难。objectForKey:如果密钥不存在,etc 将简单地返回 nil。但是objectAtIndex:0当数组中没有任何对象时会抛出一个无效的参数异常。因此,请确保检查收到的对象的长度和存在。

if (menuItems && [menuItems isKindOfClass[NSArray class]] && [menuItems count]) ... 

会做。这首先检查 menuItem 是否不为零,然后检查它是否是 NSArray(或 NSMutableArray - 也会评估为 YES)以及数组是否包含任何对象。后者也可以通过适当的 for 循环来实现。没有必要实际嵌套 if 语句,因为它从左侧开始评估,并将在所有条件都与逻辑 AND 连接时找到的第一个 NO 处停止评估&&

于 2013-03-01T16:16:58.370 回答
1

使用以下代码:

NSLog(@"%@",[[[menuItems objectForKey:@"Table"] objectAtIndex:0] objectForKey:@"MENUDESC"]);

NSLog(@"%@",[[[menuItems objectForKey:@"Table"] objectAtIndex:0] objectForKey:@"MENUID"]);

这将只返回第一个 Array :您也可以通过使用获取所有值for Loop:

于 2013-03-01T08:28:17.637 回答
0

感谢您的回复,他们真的很有帮助。我改变了NSArray *menuItems;NSDictionary *menuItems;然后这样做:

NSDictionary *tweet = [[menuItems objectForKey:@"Table"] objectAtIndex:indexPath.row];
NSString *text = [tweet objectForKey:@"MENUDESC"];
NSString *name = [tweet objectForKey:@"MENUID"];

效果很好,给了我这个结果:

2013-03-02 03:00:44.396 App Test[616:c07] HOME             ID:1072
2013-03-02 03:00:44.396 App Test[616:c07] PRODUCTS &amp; SERVICES  ID:1073
2013-03-02 03:00:44.396 App Test[616:c07] ABOUT US  ID:1074
2013-03-02 03:00:44.397 App Test[616:c07] WHAT SETS US APART  ID:1075
2013-03-02 03:00:44.397 App Test[616:c07] CASE STUDIES  ID:1126
2013-03-02 03:00:44.397 App Test[616:c07] REQUEST PROPOSAL  ID:1076
2013-03-02 03:00:44.397 App Test[616:c07] CONTACT  ID:1077
于 2013-03-02T10:56:45.677 回答