pro*_*oxi 11 key-value-observing swift-protocols swift4
我正在努力在Swift 4中使用新的强类型KVO语法来观察仅通过协议可见的属性:
import Cocoa
@objc protocol Observable: class {
var bar: Int { get }
}
@objc class Foo: NSObject, Observable {
@objc dynamic var bar = 42
}
let implementation = Foo()
let observable: Observable = implementation
let observation = observable.observe(\.bar, options: .new) { _, change in
guard let newValue = change.newValue else { return }
print(newValue)
}
implementation.bar = 50
Run Code Online (Sandbox Code Playgroud)
error: value of type 'Observable' has no member 'observe'
let observation = observable.observe(\.bar, options: .new) { _, change in
Run Code Online (Sandbox Code Playgroud)
显然,Observable不是NSObject.但我不能简单地将它NSObject强制转换,因为keypath的类型与对象的类型不匹配.
我试着更明确地说明这种类型:
let observable: NSObject & Observable = implementation
Run Code Online (Sandbox Code Playgroud)
但:
error: member 'observe' cannot be used on value of protocol type 'NSObject & Observable'; use a generic constraint instead
let observation = observable.observe(\.bar, options: .new) { _, change in
Run Code Online (Sandbox Code Playgroud)
我想做的不可能吗?这似乎是一个常见的用例.使用旧的#keypath语法很容易完成.你能提供任何其他选择吗?谢谢.
此代码在Swift 4.1.2(Xcode 9.4)中编译和运行:
import Foundation
@objc protocol Observable: AnyObject {
var bar: Int { get }
}
@objc class Foo: NSObject, Observable {
@objc dynamic var bar = 42
}
let implementation = Foo()
let observable: NSObject & Observable = implementation
func observeWrapper<T: NSObject & Observable>(_ object: T) -> NSKeyValueObservation {
return object.observe(\.bar, options: .new) { _, change in
guard let newValue = change.newValue else { return }
print(newValue)
}
}
let observation = observeWrapper(observable)
implementation.bar = 50
withExtendedLifetime(observation, {})
Run Code Online (Sandbox Code Playgroud)
我所做的只是将调用包装observe在一个受限制的泛型函数中NSObject & Observable.
尽管引入了泛型,但仍然可以将协议类型传递observable给这个新函数.说实话,我无法解释为什么会这样.
编辑:这可以解释它:Swift中的协议通常不符合自己,因此即使约束匹配,也不允许使用存在(协议类型)调用泛型函数.但是@objc协议(没有静态要求)有一个例外,它们符合自己的要求.我想这是有效的,因为Observable有标记@objc.
| 归档时间: |
|
| 查看次数: |
893 次 |
| 最近记录: |