Last active
April 23, 2020 15:20
-
-
Save daltonclaybrook/177adda6b3e07c36a2062f21089a5726 to your computer and use it in GitHub Desktop.
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
import RxSwift | |
/// This type is similar to `BehaviorRelay`, but it allows for mutating an element in-place | |
/// rather than assigning a new one. | |
/// | |
/// This is useful for large copy-on-write containers. For example, it's less expensive to append | |
/// an element to an `Array` with 1M entries than it is to make a new `Array` by concatenating it with | |
/// a second `Array` with one element. | |
public final class MutableRelay<Element>: ObservableType { | |
public private(set) var value: Element | |
private let subject = ReplaySubject<Element>.create(bufferSize: 1) | |
private let lock = NSRecursiveLock() | |
public init(value: Element) { | |
self.value = value | |
subject.onNext(value) | |
} | |
public func subscribe<Observer>(_ observer: Observer) -> Disposable where Observer: ObserverType, Element == Observer.Element { | |
subject.subscribe(observer) | |
} | |
public func accept(_ element: Element) { | |
modify { $0 = element } | |
} | |
public func modify(block: (inout Element) -> Void) { | |
lock.lock(); defer { lock.unlock() } | |
block(&value) | |
subject.onNext(value) | |
} | |
} | |
extension ObservableType { | |
public func bind<Element>(to relay: MutableRelay<Element>) -> Disposable where Self.Element == Element { | |
subscribe { event in | |
switch event { | |
case let .next(element): | |
relay.accept(element) | |
case .error, .completed: | |
break | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment