Swift派生属性KVO没有工作问题

时间:2015-12-27 00:22:15

标签: swift cocoa key-value-observing

我正在尝试实现一个NSCollectionViewItem类,该类提供从representedObject派生的只读属性,简化代码如下所示

class PersonItem : NSCollectionViewItem {
   var fullName:String! {
        get {
            if let obj = representedObject as? Person {
                return "\(obj.firstName) \(obj.lastName)"
            }
            return "none"
        }
    }
}

当然,我可以通过像

之类的东西获得价值
person.fullName

但是,我提供此属性的原因是我想将它绑定到xib文件中的UI。 KVO似乎仅适用于representedObject的更改,但如果值来自此fullName属性,则它根本不起作用。我注意到有一个类方法

keyPathsForValuesAffectingValueForKey

用于通知派生属性的更改,但我无法在Swift类中覆盖它。似乎没有提供这种方法,它说未找到,即使该类继承自NSCollectionViewItem

那么,问题是如何让KVO也适用于这个fullName属性?

1 个答案:

答案 0 :(得分:4)

三件事:首先,正如评论中提到的阳光一样,您需要使用dynamic关键字标记您的属性,以便可以使用键值编码来访问它,这是键值观察的先决条件。

其次,keyPathsForValuesAffectingValueForKey()是一种类方法。因此,要覆盖它,您必须使用:

override class func keyPathsForValuesAffectingValueForKey(_ key: String) -> Set<String> {
    // ...
}
然而,第三,不要这样做。来自keyPathsForValuesAffectingValueForKey()的文档:

  

此方法的默认实现在接收类中搜索名称与模式+keyPathsForValuesAffecting<Key>匹配的方法,并返回调用该方法的结果(如果找到)。

因此,更好的选择是实施:

dynamic class func keyPathsForValuesAffectingFullName() -> Set<String> {
    return ["representedObject.firstName", "representedObject.lastName"]
}

该方法也需要dynamic,因为它是按名称查找的。