スウィフト 3 の実装:
class MulticastDelegate<T> {
private var delegates = [Weak]()
func add(_ delegate: T) {
if Mirror(reflecting: delegate).subjectType is AnyClass {
delegates.append(Weak(value: delegate as AnyObject))
} else {
fatalError("MulticastDelegate does not support value types")
}
}
func remove(_ delegate: T) {
if type(of: delegate).self is AnyClass {
delegates.remove(Weak(value: delegate as AnyObject))
}
}
func invoke(_ invocation: (T) -> ()) {
for (index, delegate) in delegates.enumerated() {
if let delegate = delegate.value {
invocation(delegate as! T)
} else {
delegates.remove(at: index)
}
}
}
}
private class Weak: Equatable {
weak var value: AnyObject?
init(value: AnyObject) {
self.value = value
}
}
private func ==(lhs: Weak, rhs: Weak) -> Bool {
return lhs.value === rhs.value
}
extension RangeReplaceableCollection where Iterator.Element : Equatable {
@discardableResult
mutating func remove(_ element : Iterator.Element) -> Iterator.Element? {
if let index = self.index(of: element) {
return self.remove(at: index)
}
return nil
}
}
次の方法でテストできます。
protocol SomeDelegate: class {
func onSomeEvent()
}
class SomeDelegateImpl: SomeDelegate {
let value: Int
init(value: Int) {
self.value = value
}
func onSomeEvent() {
print("Invoking delegate \(value)")
}
}
let multicastDelegate = MulticastDelegate<SomeDelegate>()
func testInvoke() {
multicastDelegate.invoke {
$0.onSomeEvent()
}
}
print("Adding first delegate.")
let delegate1 = SomeDelegateImpl(value: 1)
multicastDelegate.add(delegate1)
testInvoke()
let delegate2 = SomeDelegateImpl(value: 2)
print("Adding second delegate.")
multicastDelegate.add(delegate2)
testInvoke()
print("Removing first delegate.")
multicastDelegate.remove(delegate1)
testInvoke()
print("Adding third delegate.")
({
let delegate3 = SomeDelegateImpl(value: 3)
multicastDelegate.add(delegate3)
testInvoke()
})()
print("Third delegate is deallocated by ARC.")
testInvoke()
それは印刷します:
Adding first delegate.
Invoking delegate 1.
Adding second delegate.
Invoking delegate 1.
Invoking delegate 2.
Removing first delegate.
Invoking delegate 2.
Adding third delegate.
Invoking delegate 2.
Invoking delegate 3.
Third delegate is deallocated by ARC.
Invoking delegate 2.
このブログ投稿に基づいています。