不能将泛型值转换为AnyObject,当它被AnyObject约束时



错误是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) }
}
}
}
}

是否有可能在这种情况下转换我的完成处理程序,或者在某种程度上等同于OAnyObject

根据您的类型,我可以将任何我想要的对象传递给Observer.completion的第一个参数。但是你分配给.completion的函数只能接受特定类型的O

您必须将completion更改为(AnyObject?, ObservedType) -> Void

public func observe<O: AnyObject>(forward object: O?, completion: @escaping (AnyObject?, ObservedType) -> Void) {
       ^^^^^^^^^^

你传递的函数必须处理它可以传递任何东西的事实。我怀疑这会破坏你的整个系统。但是我不相信这种风格的可观察对象会成功,因为正是这些类型问题。

没有什么好办法直接把观察者存储在Observable中。您目前没有使用它,但我假设您需要它来删除观察者之类的东西。有很多方法可以做到这一点,但是你不能存储观察者本身。您可以返回一个唯一标识符(例如UUID),或者您可以使用对象标识符,或者您可以返回"删除此项";观察者必须调用的闭包。但是你通常不希望直接存储观察者(当然也不希望作为AnyObject)。

我建议使用Combine,因为这就是它的设计目的。或者,如果你需要支持较旧的iOS版本,请查看这个实验,了解如何使其工作,或者这个实验的简化版本更接近你在这里尝试做的事情。

相关内容

  • 没有找到相关文章

最新更新