【问题标题】:Why does NSDictionary freak out when we have @ symbol in its keys? [duplicate]为什么 NSDictionary 的键中有 @ 符号时会发疯? [复制]
【发布时间】:2014-03-02 07:18:12
【问题描述】:

当我在 JSON 响应中使用 @ 符号时,我遇到了 RestKit 问题。经过一些调试,问题似乎发生在__NSCFDictionary

所以我尝试了以下简单的代码:

NSArray *keys = [NSArray arrayWithObjects:@"@key1", @"@key2", nil];
NSArray *objects = [NSArray arrayWithObjects:@"value1", @"value2", nil];
NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:objects
                                                   forKeys:keys];
for (id key in dictionary) {
    NSLog(@"key: %@, value: %@", key, [dictionary valueForKey:key]);
}

我收到以下错误:

[<__nsdictionaryi> valueForUndefinedKey:]:这个类 不符合键 key1 的键值编码。

谁能解释我为什么会收到这个错误以及是否有任何解决方法?

【问题讨论】:

    标签: objective-c cocoa nsdictionary key-value-coding


    【解决方案1】:

    您不能在键中将@valueForKey: 结合使用。 NSDictionary has some documented but perhaps unexpected behavior 在这种情况下:它会剥离 @ 并使用新密钥调用 [super valueForKey:]。这会在对象上查找键,而不是在字典的内容中。 NSDictionary 的实例上不存在这样的键,因此会引发异常。

    您通常应该使用objectForKey:NSDictionary 检索值。

    下面的 cmets 必须归功于 Ken Thomases,更正了这个答案的早期版本。

    【讨论】:

    • Awww 坚果,+1 给你,因为你的答案 (which is detailed further in this question) 比我的更正确。
    • 这有点不正确。与NSDictionary 类引用中的documented 一样,如果您在具有以@ 开头的键的字典上调用-valueForKey:,它将剥离@ 并调用super。实际上,它访问字典的属性,而不是它的键值映射。因此,[dict valueForKey:@"@allKeys"] 返回的结果与 dict.allKeys 相同。
    • 感谢@KenThomases 的更正;我已经修改并将这个问题指向了一个较早的问题,该问题对 vikingosegundo 的问题有很好的描述。
    • 不客气,但您的编辑仍然不正确。 [dict valueForKey;@"@someKey"] 不会在字典的键中查找 @"someKey" 并检索该值。它只会查看字典的inherent 属性——它提供getter 的东西。基本上,-valueForKey: 在非字典的情况下访问对象的属性。 NSDictionary 覆盖此行为,而是通过 -objectForKey: 查看它维护的键值映射。但它提供了一种绕过机制来回到非字典行为,使用这个@ 前缀。
    • 啊。再次感谢@KenThomases。如果答案不被接受,我会在这一点上删除。我已经重新编辑了。
    【解决方案2】:

    因为您复制了使用 valueForKey: 而不是 objectForKey: 的人的代码,而没有了解每个人的优点。

    objectForKey: 是你应该使用的。它获取您传入的键,并查找该键的值。

    valueForKey: 是一个非常复杂的方法,它查看键中的文本,并做各种复杂的事情,例如@“@sum”的键将添加一些值。如果那是你想要的,那很好。如果要查找值,请使用 objectForKey。它做你认为它应该做的事,而且通常比 valueForKey: 快几倍。

    根据经验:如果我问你应该使用 objectForKey: 还是 valueForKey:,而你不知道有什么区别,请使用 objectForKey:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-05
      • 1970-01-01
      • 2012-05-18
      • 1970-01-01
      相关资源
      最近更新 更多