【问题标题】:valueForKeyPath returning nil unexpectedlyvalueForKeyPath 意外返回 nil
【发布时间】:2017-01-06 05:09:48
【问题描述】:

这是一个相当短的问题,但我对如何解决它有点困惑。

for item in filteredAndSortedDates {
     print(item.datesSectionHeader()) // Returns a value
     print(item.value(forKeyPath: "datesSectionHeader") as Any) // Returns nil
     // The "as Any" part up above is just to keep the compiler quiet. It doesn't have any meaning as this is just for testing purposes.
}

我对为什么会发生这种情况有点困惑。当上面返回一个值时,valueForKeyPath 怎么会返回nil?我打电话给NSDictionary

这是我得到的日志:

HAPPENING THIS WEEK
nil
HAPPENING THIS WEEK
nil
HAPPENING THIS WEEK
nil
HAPPENING WITHIN A YEAR
nil

这是我声明datesSectionHeader的方式:

extension NSDictionary {

     // FIXME
     func datesSectionHeader() -> String {
         // Doing some work in here.
     }
}

【问题讨论】:

  • 在您的问题中打印您的日志
  • 当然!让我现在添加它。
  • print(item.value(forKeyPath: "datesSectionHeader") as NSString)
  • NSDictionary 覆盖 valueForKey: (Swift: value(forKey:)) 以返回其键的内容值,并且不检查键的 getter 方法。 (value(forKeyPath:) 内部调用 value(forKey:)。)据我测试,这种行为在 Objective-C 中也有,所以它不是 Swift 的错误。你需要找到解决办法。您可能需要使用一个以符合 KVC 的方式定义 datesSectionHeader 的类来包装字典。
  • 作为@OOPer 所说的一个皱纹,如果你在一个键前面加上“@”,那么它会访问字典的属性而不是它的内容。所以,item.value(forKeyPath: "@datesSectionHeader") 会起作用。

标签: objective-c swift key-value-coding


【解决方案1】:

NSDictionary 修改键值编码的标准行为,以便它访问字典的内容而不是其属性。它通过覆盖value(forKey:)(反过来,由value(forKeyPath:) 使用)来做到这一点。

作为documented,它对value(forKey:) 的覆盖检查密钥是否以“@”为前缀。如果不是,则返回object(forKey:) 的结果,访问字典内容。如果它以“@”为前缀,它会去除“@”并从超类的实现中返回结果,该实现会访问字典的属性。

因此,在这种特殊情况下,您可以使用以下方法从您的 datesSectionHeader() getter 方法中访问结果:

item.value(forKeyPath: "@datesSectionHeader")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-25
    • 2018-02-03
    • 1970-01-01
    • 1970-01-01
    • 2019-09-23
    • 1970-01-01
    相关资源
    最近更新 更多