Skip to content

Instantly share code, notes, and snippets.

@freedom27
Created April 7, 2016 16:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save freedom27/3bd0e83917570b4520d28e79d4554fa2 to your computer and use it in GitHub Desktop.
Save freedom27/3bd0e83917570b4520d28e79d4554fa2 to your computer and use it in GitHub Desktop.
protocol Disposable {
func dispose()
func addToDisposablesBag(bag: DisposablesBag)
}
extension Disposable {
func addToDisposablesBag(bag: DisposablesBag) {
bag.add(self)
}
}
class DisposablesBag {
private var disposables = [Disposable]()
func add(disposable: Disposable) {
disposables.append(disposable)
}
func disposeAll() {
disposables.forEach{$0.dispose()}
}
}
class Observation<T> {
typealias Observer = T->Void
let observer: Observer
weak var observed: Observable<T>?
init(observer: Observer, observed: Observable<T>) {
self.observer = observer
self.observed = observed
}
}
extension Observation: Disposable {
func dispose() {
observed?.unobserve(self)
}
}
extension Observation:Equatable { }
func ==<T>(lhs: Observation<T>, rhs: Observation<T>) -> Bool {
return lhs === rhs
}
class Observable<T> {
var value: T {
didSet {
observations.forEach{$0.observer(self.value)}
}
}
private var observations = [Observation<T>]()
init(value: T) {
self.value = value
}
func observe(observer: T->Void) -> Observation<T> {
let observation = Observation(observer: observer, observed: self)
observations.append(observation)
return observation
}
func unobserve(observation: Observation<T>) {
observations = observations.filter{$0 != observation}
}
}
let bag = DisposablesBag()
let s = Observable(value: "a string")
s.observe {(s: String) in
print(s)
}.addToDisposablesBag(bag)
s.value = "another string"
print(s.value)
s.value = "again"
bag.disposeAll()
s.value = "and again"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment