このコードは、次の 2 つの理由で機能しません。
Using Swift with Cocoa and Objective-Cの「Adopting Cocoa Design Patterns」のセクション「Key-Value Observing」で説明されているようにdynamic
、プロパティに属性を追加する必要があります。area
Key-Value Observing Programming Guideの「Registering Dependent Keys」で説明されているように、依存area
することを宣言する必要があります。(これは、Objective-C と Swift に適用されます。) これが機能するには、 and にも追加する必要があります。width
height
dynamic
width
height
willChangeValueForKey
(代わりにand didChangeValueForKey
whenwidth
またはchangesを呼び出すこともできますが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])