私は、このように美しい被験者 - 観察者パターンを実装するクラスを持っているとしましょう。 (これはスウィフト3である;。スウィフト2は、本質的には異なるないだろう)Swiftで一般的な被験者の実装を書く
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() }
}
}
(。私はとほぼ同等のデザインパターンの概念に慣用スウィフト用語「デリゲート」「オブザーバー」を取っている)
上記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
に類似した別のデリゲートプロトコルでSubject
に類似した別のクラスを作成したいです。どのように私はすでに新しいクラスのSubject
のために書いた実装を使用するのですか?
答えは、コードをコピーして貼り付けることです。良い答えではありません。
C++では、Subjectを実装するために必要なすべてのコードとデータを含むクラスで、汎用のDelegate型にテンプレート化された真のmixinを作成し、他のクラスをa件名。かなり簡単です。
プロトコル、プロトコル拡張、およびジェネリックスには、この種のコード再利用に必要な機械がいくつかあるようですが、それを達成する方法はありません。
ヘルプ?
私は誤解しているかもしれませんが、あなたの新しいクラスの 'Subject'から継承できないのでしょうか? – sdasdadas
@sdasdadas新しいクラスのペア、 'NewSubject'と' NewDelegate'が必要だとします。問題は、 'NewDelegate'が' NewDelegate'を新しいデリゲート型にするよう 'Subject'を継承するにはどうすればいいのですか?例えば' eachDelegate() 'は' NewDelegate'を取る関数を取るでしょうか? – OldPeculier