Created
November 1, 2016 01:30
-
-
Save iThinker/6b1f07a00b059e9f8f5f5d78f914b5b2 to your computer and use it in GitHub Desktop.
Observable V3
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 | |
class ObserverStorage { | |
static let shared = ObserverStorage() | |
private var observablesMap: NSMapTable<AnyObject, AnyObject> = NSMapTable.weakToStrongObjects() | |
private func subscriptionsMap<T: Observable>(forObservable observable: T) -> NSMapTable<AnyObject, AnyObject> { | |
var subscriptionsMap = self.observablesMap.object(forKey: observable) as? NSMapTable<AnyObject, AnyObject> | |
if subscriptionsMap == nil { | |
subscriptionsMap = NSMapTable.weakToWeakObjects() | |
self.observablesMap.setObject(subscriptionsMap, forKey: observable) | |
} | |
return subscriptionsMap! | |
} | |
func addObserver<U, T: Observable>(_ observer: AnyObject, subscription: U, observable: T) -> Void { | |
let subscriptionsMap = self.subscriptionsMap(forObservable: observable) | |
subscriptionsMap.setObject(subscription as AnyObject, forKey: observer) | |
} | |
func removeObserver<T: Observable>(_ observer: AnyObject, observable: T) -> Void { | |
let subscriptionsMap = self.subscriptionsMap(forObservable: observable) | |
subscriptionsMap.removeObject(forKey: observer) | |
} | |
func subscriptions<U: Observable, T>(forObservable observable: U) -> [T] { | |
return self.subscriptionsMap(forObservable: observable).objectEnumerator()?.allObjects as! [T] | |
} | |
} | |
protocol Observable: class { | |
associatedtype ObservableAction | |
typealias SubscriptionBlock = (ObservableAction) -> Void | |
func notifyObservers(_ action: ObservableAction) -> Void | |
func addObserver(_ observer: AnyObject, subscription: SubscriptionBlock) -> Void | |
func removeObserver(_ observer: AnyObject) -> Void | |
} | |
extension Observable { | |
func notifyObservers(_ action: ObservableAction) -> Void { | |
let subscriptions: [SubscriptionBlock] = ObserverStorage.shared.subscriptions(forObservable: self) | |
for subscription in subscriptions { | |
subscription(action) | |
} | |
} | |
func addObserver(_ observer: AnyObject, subscription: SubscriptionBlock) -> Void { | |
ObserverStorage.shared.addObserver(observer, subscription: subscription, observable: self) | |
} | |
func removeObserver(_ observer: AnyObject) -> Void { | |
ObserverStorage.shared.removeObserver(observer, observable: self) | |
} | |
} | |
enum TestObservableActions { | |
case testAction | |
} | |
class TestObservable: Observable { | |
internal var subscriptions: NSMapTable<AnyObject, AnyObject> = NSMapTable.weakToWeakObjects() | |
typealias ObservableAction = TestObservableActions | |
func testFunc() -> Void { | |
self.notifyObservers(.testAction) | |
} | |
} | |
class TestObserver { | |
internal func observe(_ action: TestObservableActions) { | |
print("Action: \(action)") | |
} | |
} | |
func test() -> Void { | |
let testObservable = TestObservable() | |
let testObserver = TestObserver() | |
testObservable.addObserver(testObserver, subscription: testObserver.observe) | |
testObservable.testFunc() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment