Swift 派生 属性 KVO 不工作问题
Swift derived property KVO not working issue
我正在尝试实现 NSCollectionViewItem
class,它提供从 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
属性,它根本不起作用。我注意到有一个 class 方法
keyPathsForValuesAffectingValueForKey
用于通知派生属性的更改,但我无法在 Swift class 中覆盖它。好像那里没有提供这个方法,它说找不到,即使 class 继承自 NSCollectionViewItem
.
所以,问题是如何使 KVO 也适用于此 fullName
属性?
三件事:首先,正如评论中提到的 sunshine,您需要使用 dynamic
关键字标记您的 属性 以便使用键值编码访问它,这是先决条件用于键值观察。
其次,keyPathsForValuesAffectingValueForKey()
是一种class方法。因此,要覆盖它,您必须使用:
override class func keyPathsForValuesAffectingValueForKey(_ key: String) -> Set<String> {
// ...
}
第三,但是,不要那样做。来自 keyPathsForValuesAffectingValueForKey()
的文档:
The default implementation of this method searches the receiving class for a method whose name matches the pattern +keyPathsForValuesAffecting<Key>
, and returns the result of invoking that method if it is found.
因此,更好的选择是实施:
dynamic class func keyPathsForValuesAffectingFullName() -> Set<String> {
return ["representedObject.firstName", "representedObject.lastName"]
}
该方法也需要 dynamic
,因为它是按名称查找的。
我正在尝试实现 NSCollectionViewItem
class,它提供从 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
属性,它根本不起作用。我注意到有一个 class 方法
keyPathsForValuesAffectingValueForKey
用于通知派生属性的更改,但我无法在 Swift class 中覆盖它。好像那里没有提供这个方法,它说找不到,即使 class 继承自 NSCollectionViewItem
.
所以,问题是如何使 KVO 也适用于此 fullName
属性?
三件事:首先,正如评论中提到的 sunshine,您需要使用 dynamic
关键字标记您的 属性 以便使用键值编码访问它,这是先决条件用于键值观察。
其次,keyPathsForValuesAffectingValueForKey()
是一种class方法。因此,要覆盖它,您必须使用:
override class func keyPathsForValuesAffectingValueForKey(_ key: String) -> Set<String> {
// ...
}
第三,但是,不要那样做。来自 keyPathsForValuesAffectingValueForKey()
的文档:
The default implementation of this method searches the receiving class for a method whose name matches the pattern
+keyPathsForValuesAffecting<Key>
, and returns the result of invoking that method if it is found.
因此,更好的选择是实施:
dynamic class func keyPathsForValuesAffectingFullName() -> Set<String> {
return ["representedObject.firstName", "representedObject.lastName"]
}
该方法也需要 dynamic
,因为它是按名称查找的。