用于创建 NSDictionary 的 Objective-C foreach 不起作用
Posted
技术标签:
【中文标题】用于创建 NSDictionary 的 Objective-C foreach 不起作用【英文标题】:Objective-C foreach for creating a NSDictionary not working 【发布时间】:2014-03-17 13:38:06 【问题描述】:我正在尝试使用以下代码对 NSDictionary 进行排序:
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:[str dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableLeaves error:&err];
for (NSDictionary* lesson in jsonDict[@"data"][@"lessons"])
data[lesson[@"day"]][lesson[@"index"]][@"title"] = lesson[@"title"];
如果我记录lesson[@"day"]
等的值,这些值似乎是正确的。不知何故,如果我在循环之后记录data[@"1"][@"1"]
,它只是空的。所以问题似乎在于将值设置到 NSDictionary 数据中。
原始 JSON 字符串包含一个包含所有课程的列表。为了正确访问它们,我想要一个新的 NSDictionary 格式:data[day][index][field]
JSON 代码如下所示:
"status":"success","data":"lessons":["id":1,"index":"1","day":"1","title":"Mathe","teacher":"Mr. xyz","room":"103","ind":"1","id":2,"index":"1","day":"2","title":"Physik","teacher":"Mr xyz","room":"PH4","ind":"1",...
【问题讨论】:
你能发一个 JSON 的例子吗? “重新排序字典”?说什么? NSMutableDictionary Class Reference @jackslash 我添加了 JSON 示例的一部分,尽管这不是问题。我可以成功访问数据,问题只是将它放入一个新的 NSDictionary(在 for 循环中) @Dion 问题是你不能像那样修改NSDictionary
,你需要一个可变容器,在你的情况下是NSMutableDictionary
【参考方案1】:
问题是(我假设)
data[lesson[@"day"]][lesson[@"index"]][@"title"] = lesson[@"title"];
不会自动创建中间字典
data[lesson[@"day"]]
data[lesson[@"day"]][lesson[@"index"]]
您必须先检查它们是否存在,如果它们还不存在,则分配一个可变字典 存在。 (没有 Autovivification 与 Perl 哈希一样!)类似于:
if (data[lesson[@"day"]] == nil)
data[lesson[@"day"]] = [NSMutableDictionary dictionary];
if (data[lesson[@"day"]][lesson[@"index"]] == nil)
data[lesson[@"day"]][lesson[@"index"]] = [NSMutableDictionary dictionary];
data[lesson[@"day"]][lesson[@"index"]][@"title"] = lesson[@"title"];
完整的工作代码:
NSString *str = @"\"status\":\"success\",\"data\":\"lessons\":[\"id\":1,\"index\":\"1\",\"day\":\"1\",\"title\":\"Mathe\",\"teacher\":\"Mr. xyz\",\"room\":\"103\",\"ind\":\"1\",\"id\":2,\"index\":\"1\",\"day\":\"2\",\"title\":\"Physik\",\"teacher\":\"Mr xyz\",\"room\":\"PH4\",\"ind\":\"1\"]";
NSError *err;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:[str dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableLeaves error:&err];
NSMutableDictionary *data = [NSMutableDictionary dictionary];
for (NSDictionary* lesson in jsonDict[@"data"][@"lessons"])
if (data[lesson[@"day"]] == nil)
data[lesson[@"day"]] = [NSMutableDictionary dictionary];
if (data[lesson[@"day"]][lesson[@"index"]] == nil)
data[lesson[@"day"]][lesson[@"index"]] = [NSMutableDictionary dictionary];
data[lesson[@"day"]][lesson[@"index"]][@"title"] = lesson[@"title"];
NSLog(@"%@", data);
输出:
1 = 1 = 标题=数学; ; ; 2 = 1 = 标题=物理; ; ;【讨论】:
这看起来完全正确,实际上正是我正在寻找的东西,但不知何故它也不起作用:/如果我完全采用您的代码,则会出现错误“未找到编写字典元素的预期方法在“NSDictionary *”类型的对象上,如果我将其更改为 setValue:... forKey:... 输出仍然为空,并且内容不会像以前那样写入新的 NSDictionary :( @Dion:第一条错误消息意味着你有一个(不可变的)NSDictionary,而不是一个 NSMutableDictionary。并且你应该使用setObject:forKey
来设置字典值,除非你有特定的理由使用Key-Value编码方式setValue:forKey:
。 - 我已经用您的输入数据测试了代码,它似乎可以工作。查看更新的答案。
它没有立即起作用的原因是我的错。您的回答完全正确并且有效:) 非常感谢!【参考方案2】:
NSJSONSerialization 创建字典和数组,其中填充了其他字典、数组和 NSString、NSNumber 或 NSNull 类型的值。
您应该重新考虑编写极其复杂的代码行的策略,但要逐个提取内容,以减少混乱,并使调试成为可能。喜欢
NSDictionary* data = jsonDict [@"data"];
NSArray* lessons = data [@"lessons"];
for (NSDictionary* lesson in lessons)
NSString* lessonDay = lesson [@"day"];
...
等等(如果您不一次又一次地查找相同的东西,它也会使您的代码运行得更快)。
现在到您的错误所在的位置:dict [@"key"] = data;调用 setObject:forKey: 。但是, dict [@"key1"] [@"key2"] 在字典上调用 objectForKey: @"key1" ,这会给你一个 nil 值,然后 setObjectForKey: 将被一个 nil 接收器调用。
【讨论】:
嗯,好的,谢谢您的回答,但究竟如何才能解决这个问题?以上是关于用于创建 NSDictionary 的 Objective-C foreach 不起作用的主要内容,如果未能解决你的问题,请参考以下文章
我的 NSDictionary 在我的 IBAction 中变为零
用于回调的 iOS NSError/NSDictionary
用于 JSON 解析的 NSDictionary 或自定义 NSObject
writeToFile 不适用于 NSDictionary [重复]