Skip to content

Instantly share code, notes, and snippets.

@SebastianBoldt
Last active June 19, 2018 15:40
Show Gist options
  • Save SebastianBoldt/708122704ce4d8aa94509680fd642430 to your computer and use it in GitHub Desktop.
Save SebastianBoldt/708122704ce4d8aa94509680fd642430 to your computer and use it in GitHub Desktop.
Multicast delegate in swift
import Foundation
internal final class MulticastDelegate<T> {
private var delegates = [Weak]()
func add(_ delegate: T) {
if Mirror(reflecting: delegate).subjectType is AnyClass {
let weakValue = Weak(value: delegate as AnyObject)
guard delegates.index(of: weakValue) == nil else {
return
}
delegates.append(weakValue)
} else {
fatalError("Multicast delegates do not support value types")
}
}
func remove(_ delegate: T) {
if Mirror(reflecting: delegate).subjectType is AnyClass {
let weakValue = Weak(value: delegate as AnyObject)
guard let index = delegates.index(of: weakValue) else {
return
}
delegates.remove(at: index)
}
}
func invoke(_ invocation: (T) -> Void) {
var indices = IndexSet()
for (index, delegate) in delegates.enumerated() {
if let delegate = delegate.value as? T {
invocation(delegate)
} else {
indices.insert(index)
}
}
self.removeObjects(atIndices: indices)
}
private func removeObjects(atIndices indices: IndexSet) {
let indexArray = Array(indices).sorted(by: >)
for index in indexArray {
delegates.remove(at: index)
}
}
internal func numberOfDelegates() -> Int {
return delegates.count
}
}
private final class Weak: Equatable {
weak var value: AnyObject?
init(value: AnyObject) {
self.value = value
}
static func == (lhs: Weak, rhs: Weak) -> Bool {
return lhs.value === rhs.value
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment