Last active
June 19, 2018 15:40
-
-
Save SebastianBoldt/708122704ce4d8aa94509680fd642430 to your computer and use it in GitHub Desktop.
Multicast delegate in swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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