Skip to content

Instantly share code, notes, and snippets.

@bretsko
Last active August 11, 2022 23:57
Show Gist options
  • Save bretsko/e6e823252ffd0948bff5518cef1cc428 to your computer and use it in GitHub Desktop.
Save bretsko/e6e823252ffd0948bff5518cef1cc428 to your computer and use it in GitHub Desktop.
DispatchCenter
protocol SomeProtocol1: AnyObject {
func doSth1()
}
protocol SomeProtocol2: AnyObject {
func doSth2()
}
class Subscriber1: SomeProtocol1 {
init() {}
func doSth1() {
print("doSth1")
}
}
class Subscriber2: SomeProtocol2 {
func doSth2() {
print("doSth2")
}
}
// Add or remove all observers of type
class DispatchCenter {
private typealias WeakArray<T> = [() -> T?]
private var observers1: WeakArray<SomeProtocol1> = []
private var observers2: WeakArray<SomeProtocol2> = []
//MARK: - Notify
func notifySomeProtocol1() {
observers1.forEach { $0()?.doSth1() }
}
func notifySomeProtocol2() {
observers2.forEach { $0()?.doSth2() }
}
//MARK: - Add observer
func addObserver(_ observer: SomeProtocol1) {
observers1.append({ [weak observer] in return observer })
}
func addObserver(_ observer: SomeProtocol2) {
observers2.append({ [weak observer] in return observer })
}
}
class DispatchTripManager {
let dispatchCenter = DispatchCenter()
func test() {
print("test")
let a = Subscriber1()
let b = Subscriber2()
dispatchCenter.addObserver(a)
dispatchCenter.addObserver(b)
dispatchCenter.notifySomeProtocol1()
dispatchCenter.notifySomeProtocol2()
}
}
// ------------ Editable
// Add and remove any specific observer
class DispatchCenter2 {
private typealias WeakObj<T> = () -> T?
private var observers1: [ String: [ WeakObj<SomeProtocol1> ] ] = [:]
//MARK: - Notify
func notifySomeProtocol1() {
observers1["\(SomeProtocol1.self)"]?.forEach{ $0()?.doSth1() }
}
//MARK: - Add observer
func addObserver(_ observer: SomeProtocol1) {
if let observers = observers1["\(SomeProtocol1.self)"],
observers.contains(where: {
$0() === observer
}) {
return
}
if let observers = observers1["\(SomeProtocol1.self)"],
!observers.isEmpty {
observers1["\(SomeProtocol1.self)"]?.append({ [weak observer] in return observer })
} else {
observers1["\(SomeProtocol1.self)"] = [ { [weak observer] in return observer } ]
}
printCount()
}
//MARK: - Remove observer
func removeObserver(_ observer: SomeProtocol1) {
observers1["\(SomeProtocol1.self)"]?.removeAll(where: {
$0() === observer
})
printCount()
}
func removeObserversOfSomeProtocol1() {
observers1.removeValue(forKey: "\(SomeProtocol1.self)")
printCount()
}
func printCount() {
print("Has \(observers1["\(SomeProtocol1.self)"]?.count ?? 0)")
}
}
class DispatchTripManager2 {
var dispatchCenter = DispatchCenter2()
func test() {
testAddObserver()
testRemoveObserver()
testRemoveObserversOfSomeProtocol1()
testaddObserverTwice()
}
func testAddObserver() {
dispatchCenter = DispatchCenter2()
print("-- testAddObserver --")
let a = Subscriber1()
dispatchCenter.addObserver(a)
dispatchCenter.notifySomeProtocol1()
print("-- finish --")
}
func testRemoveObserver() {
dispatchCenter = DispatchCenter2()
print("-- testRemoveObserver --")
let a = Subscriber1()
dispatchCenter.addObserver(a)
dispatchCenter.removeObserver(a)
dispatchCenter.notifySomeProtocol1()
print("-- finish --")
}
func testRemoveObserversOfSomeProtocol1() {
dispatchCenter = DispatchCenter2()
print("-- testRemoveObservers of SomeProtocol1 --")
let a = Subscriber1()
dispatchCenter.addObserver(a)
dispatchCenter.removeObserversOfSomeProtocol1()
dispatchCenter.notifySomeProtocol1()
print("-- finish --")
}
func testaddObserverTwice() {
dispatchCenter = DispatchCenter2()
print("-- test add the same observer twice--")
let a = Subscriber1()
dispatchCenter.addObserver(a)
dispatchCenter.addObserver(a)
dispatchCenter.notifySomeProtocol1()
print("-- finish --")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment