使用indexPath.row从多级数组中提取字典

时间:2013-03-01 08:13:53

标签: objective-c xcode json nsarray nsdictionary

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

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 个答案:

答案 0 :(得分:2)

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

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

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

JSONObject是您当前分配给menuItems的地方。在此之后,menuItems指向一系列字典,每个字典都应该能够为您提供所需的字符串。

答案 1 :(得分:1)

使用以下代码:

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

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

这将仅返回第一个数组:您也可以使用for Loop:

获取所有值

答案 2 :(得分:1)

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

因此每个{}都将转换为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
}

通过这样做,您可以为应用程序提供正确反应的机会,即使它无法处理数据。这远比你目前观察到的未被捕获的异常导致的中止要好得多。

准备接收空数组和字典。对于dictionarys来说并不困难。如果密钥不存在,objectForKey:等将返回nil。但是当数组中没有任何对象时,objectAtIndex:0将抛出无效的参数异常。因此,请务必检查收到的物体的长度和存在。

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

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

答案 3 :(得分: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