the*_*tic 5 generics weak-references observer-pattern swift
我正在尝试实现一个允许我存储一组弱观察者的结构.
这是观察者包装器:
public func ==<T: Hashable>(lhs: WeakObserver<T>, rhs: WeakObserver<T>) -> Bool {
return lhs.hashValue == rhs.hashValue
}
public struct WeakObserver<T where T: AnyObject, T: Hashable> : Hashable {
private weak var weakObserver : T?
public init(weakObserver: T){
self.weakObserver = weakObserver
}
public var hashValue : Int {
return self.weakObserver!.hashValue
}
}
Run Code Online (Sandbox Code Playgroud)
这是每个观察者需要遵守的协议:
public protocol DataModelObserverProtocol : class, Hashable, AnyObject {
func someFunc()
}
Run Code Online (Sandbox Code Playgroud)
用法:
public class DataModel: NSObject, DataModelInterface {
public var observers = Set<WeakObserver<DataModelObserverProtocol>>()
//^^^^^ Using 'DataModelObserverProtocol' as a concrete type conforming to protocol 'AnyObject' is not supported
}
Run Code Online (Sandbox Code Playgroud)
现在,虽然我知道这可能是Swift本身的限制,但我正在寻找一种替代解决方案,而没有具体的类作为类型约束(如果这不可能,我担心是这种情况,我仍然会喜欢获得替代的"非hacky"解决方案).
我知道会有更好的方法来做到这一点,但对于这样一个简单的概念来说,它似乎太复杂了,所以我采用了不同的方法:
我只是使用NSNotificationCenter并重构了我的代码,使其不必具有紧密耦合的结构,因此我没有从通知中传递信息,而是设法以一种适合我的方式抽象它,即通知不需要传递参数给他们的观察者。由于通知仅支持通过userInfo字典传递信息,因此我不得不考虑这一点。
因此,正如我所提到的,我需要一种上下文解耦的方法来做到这一点。这是一个非常抽象的答案,但我认为它可能会帮助某人规避必须搞乱“功能失调的泛型”的问题。
为了通知我的观察者,我只需注册他们:
NSNotificationCenter.defaultCenter().addObserver(...)
Run Code Online (Sandbox Code Playgroud)
并发布不带参数的通知:
NSNotificationCenter.defaultCenter().postNotification...
Run Code Online (Sandbox Code Playgroud)
我已经在之前的项目中使用过内置函数NSNotificationCenter,并且我完全了解其内部工作原理,但最初我打算将信息传递给观察者,这就是为什么我想对它进行更多限制,以创建某种形式WeakSet。
这在我的情况下再次起作用,因为我的观察者不一定需要传递可观察的细节,因为它通常是存在的并且可以被观察者访问(这是我的结构提供的东西,在读者的情况下可能不是这样) 。很难解释它,以便让阅读本文的任何人都有意义,但我对WeakSet提议的内容感到非常沮丧,所以我同意了。它更具可读性(尽管第三方可能不太容易理解),而且它似乎更适合我的用例。