gpt4 book ai didi

swift - 在 Swift 中编写一个通用的主题-观察者实现

转载 作者:可可西里 更新时间:2023-10-31 23:13:40 24 4
gpt4 key购买 nike

假设我有一个类实现了一个漂亮的主题-观察者模式。 (这是 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 术语“委托(delegate)”大致等同于设计模式概念“观察者”。)

上面的 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?
}

现在我想用另一个类似于 Delegate 的委托(delegate)协议(protocol)创建另一个类似于 Subject 的类。如何在新类中使用我已经为 Subject 编写的实现?

一个答案是复制并粘贴代码。不是一个好的答案。

在 C++ 中,我们可以创建一个真正的 mixin,一个包含实现 Subject 所需的所有代码和数据的类,以通用委托(delegate)类型为模板,并在我们想让其他类充当 Subject 的任何地方继承它.非常微不足道。

协议(protocol)、协议(protocol)扩展和泛型似乎具有这种代码重用所必需的一些机制,但我不知道如何实现它。

帮忙吗?

最佳答案

您可以使用协议(protocol)继承和泛型来派生一些基本协议(protocol)。

每个新委托(delegate)都将继承自一个父类:

protocol Delegate: class {

func method()
}

protocol DelegateA: Delegate { }

protocol DelegateB: Delegate { }

您的父主题类可以使用符合您的父协议(protocol)的泛型来实现。

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() }
}
}

每个新主题都可以实例化为符合您的子委托(delegate)的泛型。

class SubjectA<T: DelegateA>: Subject<T> { }

class SubjectB<T: DelegateB>: Subject<T> { }

关于swift - 在 Swift 中编写一个通用的主题-观察者实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41170451/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com