gpt4 book ai didi

swift4 - KVO 在 Swift 4 中观察协议(protocol)

转载 作者:行者123 更新时间:2023-12-04 02:14:29 40 4
gpt4 key购买 nike

我正在努力使用 Swift 4 中新的强类型 KVO 语法来观察仅通过协议(protocol)可见的属性:

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
error: value of type 'Observable' has no member 'observe'
let observation = observable.observe(\.bar, options: .new) { _, change in

显然, Observable不是 NSObject .但我不能简单地将其转换为 NSObject ,因为 keypath 的类型将与对象的类型不匹配。

我尝试更明确地说明类型:
let observable: NSObject & Observable = implementation

但:
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

我想做的事是不可能的吗?这似乎是一个常见的用例。使用旧的#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, {})

我所做的只是将调用转至 observe在限制为 NSObject & Observable 的通用函数中.

尽管引入了泛型,但仍然可以传递协议(protocol)类型的 observable到这个新功能。老实说,我无法真正解释为什么会这样。

编辑:这可以解释它: protocols in Swift generally don't conform to themselves ,因此即使约束匹配,也不允许调用具有存在(协议(protocol)类型)的泛型函数。但是 @objc 有一个异常(exception)。协议(protocol)(没有静态要求),它们确实符合自己的要求。我想这是因为 Observable标记为 @objc .

关于swift4 - KVO 在 Swift 4 中观察协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47199946/

40 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com