我很难从多级数组中提取字典,该数组声明为:
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 & 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 & 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"];
答案 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 & 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