【发布时间】:2021-08-10 16:06:33
【问题描述】:
我想创建一组弱引用来实现可观察功能的协议。 如果可能的话,这个协议应该有一个关联的类型,所以我不需要为每种类型创建相同的类型。
但是在 Swift 4 中这似乎不起作用,我想要的基本上是这样的:
protocol DelegateBase: AnyObject {
associatedtype Item
func onDataUpdated(data: [Item])
}
protocol Delegate : DelegateBase where Item == Int {
// Will have func onDataUpdated(data: [Int])
}
// T should be a class implementing Delegate, but cannot find a way to
// define T in a way that the Swift compiler accepts it
class WeakListener<T> {
weak var listener : T?
init(listener: T) {
self.listener = listener
}
}
class Implementation {
val listeners = [WeakListener<Delegate>]()
}
如果我将所有内容都定义为非泛型,我可以让它工作,但我希望不必为我想要支持的每种类型复制粘贴具体版本的 DelegateBase。
// This works but is clunky
protocol DelegateA {
func onDataUpdated(data: [Int])
}
// DelegateB with type Double, DelegateC with type X
class WeakListenerA {
weak var listener : DelegateA?
init(listener: DelegateA) {
self.listener = listener
}
}
// WeakListenerB with type Double, WeakListenerC with type X
class ImplementationA {
val listeners = [WeakListenerA]()
}
// ImplementationB with type Double, ImplementationC with type X
编辑:预期用途
基本上我想实现远程支持的存储库,其中 UIViewControllers 可以监听存储库内发生的事件,即使它们没有主动请求数据。
我希望监听器是通用的,所以我不需要为每种类型克隆所有内容。我想要弱引用,从那时起,除了添加侦听器之外,不需要任何手动操作来管理它们。
protocol DelegateBase: AnyObject {
associatedtype Item
func onDataModified(data: [Item])
func onDataRefreshed(data: [Item])
}
protocol IntDelegate : DelegateBase where Item == Int {
// Will have
//func onDataModified(data: [Int])
//func onDataRefreshed(data: [Int])
}
// Listener should implement the delegate T, that extends DelegateBase
// with a type
class WeakListener<T : DelegateBase> {
weak var listener : T?
init(listener: T) {
self.listener = listener
}
}
class IntRepository {
var listeners = [WeakListener<IntDelegate>]()
var data = [Int]()
func addListener(_ listener: IntDelegate /* UIViewController implementing IntDelegate*/) {
listeners.add(listener)
}
func add() {
// data is updated, notify weak listeners
data.append(1)
for listener in listeners {
listener.listener?.onDataModified(data: data)
}
}
func refresh() {
// data refreshed from a remote source
for listener in listeners {
listener.listener?.onDataRefreshed(data: data)
}
}
fileprivate func cleanupListeners() {
self.listeners = self.listeners.filter({$0.listener != nil})
}
// Singleton for example
fileprivate static var _instance: IntImplementation!
public class func shared() -> IntImplementation {
if _instance == nil {
_instance = IntImplementation()
}
return _instance!
}
}
class IntViewController: UIViewController, IntDelegate {
override func viewDidLoad() {
IntImplementation.shared().addListener(self)
}
func onDataModified(data: [Int]) {
// update UI
}
func onDataRefreshed(data: [Int]) {
// update UI
}
}
【问题讨论】:
标签: swift generics delegates protocols