不确定我是否正确命名了问题,但这里是:

假设我有一个从 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/

10-14 21:46