Swift 对象上的 KVO 符合协议
Swift KVO on an object conforming to a protocol
我有一个协议 (X) 和一个实现协议 X 的 class (A):
protocol X, NSObjectProtocol {
var toBeObserved: MyCustomClass? { get}
}
class A: NSObject, X {
var toBeObserved: MyCustomClass?
...
}
在另一个 class 我想观察变量 toBeObserved
:
class B {
...
var instanceConformingToX: X <-note: not A but simply the protocol X
...
func someFunc() {
self.observation = self.observe(\.instanceConformingToX.toBeObserved) { (observed, change) in
...
}
}
}
}
这里等式的所有部分都是或符合 NSObject,所以我希望能够 KVO toBeObserved
但我遇到了运行时崩溃:
Fatal error: Could not extract a String from KeyPath Swift.KeyPath<MyAppName.B, MyFramework.A>
谢谢。
确保将观察到的 属性 标记为 @objc
和 dynamic
。正如 Using Key-Value Observing in Swift 所说:
Mark properties that you want to observe through key-value observing with both the @objc
attribute and the dynamic
modifier.
协议和参与 类 也需要标记 @objc
。例如:
class MyCustomClass: NSObject { ... }
@objc protocol X: NSObjectProtocol {
@objc dynamic var toBeObserved: MyCustomClass? { get }
}
class A: NSObject, X {
var toBeObserved: MyCustomClass? = MyCustomClass()
}
class B: NSObject {
@objc var x: X = A()
var token: NSKeyValueObservation?
func addObserver() {
token = observe(\.x.toBeObserved) { object, _ in
print(object)
}
}
}
我有一个协议 (X) 和一个实现协议 X 的 class (A):
protocol X, NSObjectProtocol {
var toBeObserved: MyCustomClass? { get}
}
class A: NSObject, X {
var toBeObserved: MyCustomClass?
...
}
在另一个 class 我想观察变量 toBeObserved
:
class B {
...
var instanceConformingToX: X <-note: not A but simply the protocol X
...
func someFunc() {
self.observation = self.observe(\.instanceConformingToX.toBeObserved) { (observed, change) in
...
}
}
}
}
这里等式的所有部分都是或符合 NSObject,所以我希望能够 KVO toBeObserved
但我遇到了运行时崩溃:
Fatal error: Could not extract a String from KeyPath Swift.KeyPath<MyAppName.B, MyFramework.A>
谢谢。
确保将观察到的 属性 标记为 @objc
和 dynamic
。正如 Using Key-Value Observing in Swift 所说:
Mark properties that you want to observe through key-value observing with both the
@objc
attribute and thedynamic
modifier.
协议和参与 类 也需要标记 @objc
。例如:
class MyCustomClass: NSObject { ... }
@objc protocol X: NSObjectProtocol {
@objc dynamic var toBeObserved: MyCustomClass? { get }
}
class A: NSObject, X {
var toBeObserved: MyCustomClass? = MyCustomClass()
}
class B: NSObject {
@objc var x: X = A()
var token: NSKeyValueObservation?
func addObserver() {
token = observe(\.x.toBeObserved) { object, _ in
print(object)
}
}
}