该代码不起作用有两个原因:
您必须将dynamic
属性添加到属性,如Using Swift with Cocoa and Objective-C中“采用 Cocoa 设计模式”area
下的“键值观察”部分所述。
您必须声明area
依赖,width
并且height
如Key-Value Observing Programming Guide中的“注册依赖键”中所述。(这适用于 Objective-C 和 Swift。)要使其工作,您还必须dynamic
添加width
和height
.
(您可以改为调用willChangeValueForKey
和didChangeValueForKey
无论何时width
或height
更改,但通常更容易实现keyPathsForValuesAffectingArea
。)
因此:
import Foundation
class MyObject: NSObject {
@objc dynamic var width: Double = 0
@objc dynamic var height: Double = 0
@objc dynamic private var area: Double {
return width * height
}
@objc class func keyPathsForValuesAffectingArea() -> Set<String> {
return [ "width", "height" ]
}
func register() {
self.addObserver(self, forKeyPath: "area", options: [ .old, .new ], context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
print("observed \(keyPath) \(change)")
}
}
let object = MyObject()
object.register()
object.width = 20
object.height = 5
输出:
observed Optional("area") Optional([__C.NSKeyValueChangeKey(_rawValue: new): 0, __C.NSKeyValueChangeKey(_rawValue: kind): 1, __C.NSKeyValueChangeKey(_rawValue: old): 0])
observed Optional("area") Optional([__C.NSKeyValueChangeKey(_rawValue: new): 100, __C.NSKeyValueChangeKey(_rawValue: kind): 1, __C.NSKeyValueChangeKey(_rawValue: old): 0])