Last active
August 11, 2022 23:57
-
-
Save bretsko/e6e823252ffd0948bff5518cef1cc428 to your computer and use it in GitHub Desktop.
DispatchCenter
This file contains hidden or 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
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