不确定我是否正确命名了问题,但这里是:
假设我有一个从 API 返回的 JSON 响应。使用 SBJson
解析 JSON,该代码完美无缺。 JSON 示例:
{
"value": 15199, //this field is required
"value_str": "$1.5k", //this field is required
"change": 33 //this field is optional
}
现在这在一个整洁的小
NSDictionary
中被解析,我可以从中读取。到目前为止,我是这样的://lets assume that "dict" is the parsed JSON using SBJSON
NSDictionary *number = @{@"value_str": [dict objectForKey:@"value_str"]}; //this works
number = @{@"value_str": [dict objectForKey:@"value_str"], @"change": [dict objectForKey:@"change"]}; //this crashes if there was no "change" in JSON
所以发生崩溃是因为我试图将
nil
值设置为不允许的 NSDictionary
的对象。如果 change
字段始终存在,这将起作用。如何解决这个问题?我真的必须这样做:
NSDictionary *number = [NSDictionary dictionary];
[number setValue:[dict objectForKey:@"value_str"] forKey:@"value_str"];
[number setValue:[dict objectForKey:@"change"] forKey:@"change"];
等等对于字典中的每个键值对?这写起来更慢也更痛苦。必须有更好的方法,对吗?请? :)
哦,如果我设置
setValue ForKey
然后像 objectForKey
这样的查询,我会得到我用 setValue ForKey
设置的对象(或值)吗?编辑: 我有一个想法,但我不确定如何有效地实现它。而不是在这里检查每个键等等,为什么不将
NSDictionary
子类化并覆盖我认为是 @{}
的 dictionaryWithObjectsAndKeys
构造函数。我熟悉编译器 va_list
s,但我没有足够的知识来有效地实现这样的构造函数。如果有人会这样做,那就太棒了。整个想法是检查该构造函数方法中的值,如果对象是
nil
则跳过它。怎么样?有人可以让它打勾还是一个坏主意?EDIT2: 发现子类化是一个坏主意:) 使用了评论中提供的解决方案。
最佳答案
关于第一个问题,我认为最好的办法是每次都检查值(value),或者制作字典的副本。
关于第二个问题:objectForKey:
接受任何对象作为键,而不仅仅是字符串。唯一的要求是 key 支持 NSCopying
协议(protocol)。
另一个区别是,如果你给 setValue:forKey:
一个 nil 值,它会从字典中删除键(如果它存在),否则什么都不做。但是如果你给 setObject:forKey:
一个 nil 值,它会引发一个异常。
当您执行 valueForKey:
时,您需要给它一个 NSString
,而 objectForKey:
可以将任何 NSObject
子类作为键。这是因为对于键值编码,键总是字符串。
事实上,文档指出,即使你给 valueForKey:
一个 NSString
,它也会调用 objectForKey:
,除非字符串以 @ 开头,在这种情况下它调用 [super valueForKey:]
,它可能调用 valueForUndefinedKey:
,这可能会引发异常。
关于ios - NSDictionary 具有 nil 值的快速 KVC,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20759881/