假设我有一个类,它实现了一个漂亮的主题观察者模式。(这是Swift 3;Swift 2在本质上不会有什么不同。)
protocol Delegate : class
{
func method()
}
class Subject
{
private typealias WeakDelegate = WeakReference< Delegate >
private var nextAvailableDelegateId = 0
private var delegates = [ Int : WeakDelegate ]()
@discardableResult
public func addDelegate( _ delegate: Delegate ) -> Int
{
let id = nextAvailableDelegateId
nextAvailableDelegateId += 1
delegates[ id ] = WeakDelegate( value: delegate )
return id
}
public func removeDelegate( _ idForDelegate: Int )
{
delegates.removeValue( forKey: idForDelegate )
}
fileprivate func eachDelegate( fn: (Delegate) -> Void )
{
for (key, weakDelegate) in delegates
{
// Has this weak delegate reference become nil?
//
guard let delegate = weakDelegate.value else
{
// Yes. Remove it.
delegates.removeValue( forKey: key )
continue
}
fn( delegate )
}
}
private func exampleNotifier()
{
eachDelegate{ $0.method() }
}
}
(我将惯用的swift术语“委托”大致等同于设计模式概念“观察者”。)
上面的
WeakReference
类型并不是这个问题的一部分,但是如果你好奇的话:public class WeakReference< T >
{
public var value: T?
{
return abstractValue as? T
}
public init( value: T )
{
abstractValue = value as AnyObject
}
private weak var abstractValue: AnyObject?
}
现在,我想用另一个类似于
Subject
的委托协议创建另一个类似于Delegate
的类。如何在新类中使用已经为Subject
编写的实现?一个答案是复制和粘贴代码。回答不好。
在C++中,我们可以创建一个真正的MIXIN,一个包含实现该主题所需的所有代码和数据的类,在泛型委托类型上模板化,并继承它,无论我们想把其他类动作作为主题。相当微不足道。
协议、协议扩展和泛型似乎具有这种代码重用所必需的一些机制,但我无法解决如何实现它。
帮助?
最佳答案
您可以使用协议继承和泛型从一些基本协议派生。
每个新委托都将从父类继承:
protocol Delegate: class {
func method()
}
protocol DelegateA: Delegate { }
protocol DelegateB: Delegate { }
您的父主题类可以使用符合父协议的泛型实现。
class Subject<T: Delegate> {
private typealias WeakDelegate = WeakReference<T>
private var nextAvailableDelegateId = 0
private var delegates = [Int: WeakDelegate]()
@discardableResult
public func addDelegate(_ delegate: T) -> Int {
let id = nextAvailableDelegateId
nextAvailableDelegateId += 1
delegates[id] = WeakDelegate( value: delegate )
return id
}
public func removeDelegate(_ idForDelegate: Int) {
delegates.removeValue(forKey: idForDelegate)
}
fileprivate func eachDelegate( fn: (T) -> Void ) {
for (key, weakDelegate) in delegates {
// Has this weak delegate reference become nil?
guard let delegate = weakDelegate.value else {
// Yes. Remove it.
delegates.removeValue( forKey: key )
continue
}
fn( delegate )
}
}
private func exampleNotifier() {
eachDelegate{ $0.method() }
}
}
每个新主题都可以实例化为符合您的子委托的通用主题。
class SubjectA<T: DelegateA>: Subject<T> { }
class SubjectB<T: DelegateB>: Subject<T> { }
关于swift - 在Swift中编写一个共同的主题 - 观察者实现,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41170451/