错误是 Cannot convert value of type '(O?, ObservedType) -> Void' to expected argument type '(AnyObject?, ObservedType) -> Void
,但我觉得这很奇怪,因为 O
被限制为 AnyObject
。
对于上下文,我正在创建自己的 Observable 类,但这个问题实际上是关于上面的特定错误消息,而不是我如何使用任何其他第三方框架来使用 observable。也就是说,在这种情况下我如何正确地转换我的完成处理程序。
public class Observable<ObservedType> {
struct Observer<ObservedType> {
weak var observer: AnyObject?
let completion: (AnyObject?, ObservedType) -> Void
}
private var observers: [Observer<ObservedType>]
public var value: ObservedType? {
didSet {
if let _ = value {
notifyObservers()
}
}
}
public init(_ value: ObservedType? = nil) {
self.value = value
observers = []
}
public func observe<O: AnyObject>(forward object: O?, completion: @escaping (O?, ObservedType) -> Void) {
observers.append(Observer(observer: object, completion: completion)) // error here
if let value = value {
completion(object, value)
}
}
private func notifyObservers() {
for observer in observers {
if let value = value {
DispatchQueue.main.async { observer.completion(nil, value) }
}
}
}
}
在这种情况下是否可以强制转换我的完成处理程序,或者以某种方式等同于 O
和 AnyObject
答案 0 :(得分:1)
根据你的类型,我可以将任何我想要的对象传递给Observer.completion
的第一个参数。但是您分配给 .completion
的函数只能接受某些特定类型 O
。
您必须将 completion
更改为 (AnyObject?, ObservedType) -> Void
。
public func observe<O: AnyObject>(forward object: O?, completion: @escaping (AnyObject?, ObservedType) -> Void) {
^^^^^^^^^^
你传递的函数将不得不处理它可以传递任何东西的事实。我怀疑这会破坏你的整个系统。但我不相信这种 Observable 风格会奏效,因为正是这些类型的问题。
直接将 Observer 存储在 Observable 中真的没有什么好方法。您目前没有使用它,但我假设您想要它用于删除观察者之类的事情。有办法做到这一点,但你不能存储观察者本身。你可以返回一个唯一的标识符(例如 UUID),或者你可以使用 ObjectIdentifiers 或者你可以传回观察者必须调用的“删除这个项目”闭包。但是您通常不想直接存储观察者(绝对不是作为 AnyObject)。
我建议为此使用Combine,因为它就是为此而设计的。或者,如果您需要支持较旧的 iOS 版本,请参阅 this experiment 了解实现此功能的方法,或参阅 this experiment 了解更接近您在此处尝试执行的操作的简化版本。