参考文档
Observable & Sink & Producer
简单的关联描述,一个Observable可以是一个构造方法(observableFactory),可以是一个匿名对象(anonymouseObservable),基于需求,可以立刻创建也可以延迟创建(Deffered),这个与Observer订阅的时机有密切,于是在Observable之下建立了一层Producer,用于控制subscribe的时机触发,同时对订阅的ObserverType提供一个ObservableSink用于封装,一是控制订阅行为的取消,二是将Observable对象与Observer对象相关联,实现不同的业务需求.
Producer
遵循Observable协议的对象,最主要的方法是
subscribe,获得observer订阅的时机,并触发observable.run
run是根方法,确保继承Producer的observable类在subscribe时才执行run行为。
class Producer<Element>: Observable<Element> {
override init() {
super.init()
}
override func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
if !CurrentThreadScheduler.isScheduleRequired {
// The returned disposable needs to release all references once it was disposed.
let disposer = SinkDisposer()
let sinkAndSubscription = self.run(observer, cancel: disposer)
disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)
return disposer
}
else {
return CurrentThreadScheduler.instance.schedule(()) { _ in
let disposer = SinkDisposer()
let sinkAndSubscription = self.run(observer, cancel: disposer)
disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)
return disposer
}
}
}
func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element {
rxAbstractMethod()
}
}
Sink
遵循Disposable,主要目的是封装订阅的Observer,一是可以通过dispose()取消订阅,避免在错误和结束后订阅继续进行,主要实现方法dispose(),二是分派事件,实现前转时的内部逻辑处理,主要方法forwardOn.
class Sink<Observer: ObserverType>: Disposable {
fileprivate let observer: Observer
fileprivate let cancel: Cancelable
private let disposed = AtomicInt(0)
#if DEBUG
private let synchronizationTracker = SynchronizationTracker()
#endif
init(observer: Observer, cancel: Cancelable) {
#if TRACE_RESOURCES
_ = Resources.incrementTotal()
#endif
self.observer = observer
self.cancel = cancel
}
final func forwardOn(_ event: Event<Observer.Element>) {
#if DEBUG
self.synchronizationTracker.register(synchronizationErrorMessage: .default)
defer { self.synchronizationTracker.unregister() }
#endif
if isFlagSet(self.disposed, 1) {
return
}
self.observer.on(event)
}
final func forwarder() -> SinkForward<Observer> {
SinkForward(forward: self)
}
final var isDisposed: Bool {
isFlagSet(self.disposed, 1)
}
func dispose() {
fetchOr(self.disposed, 1)
self.cancel.dispose()
}
deinit {
#if TRACE_RESOURCES
_ = Resources.decrementTotal()
#endif
}
}
SinkDisposer
关于订阅取消,与producer使用sinkDisposer对于取消进行处理,其持有的枚举
private enum DisposeState: Int32 {
case disposed = 1
case sinkAndSubscriptionSet = 2
}
private let state = AtomicInt(0)
这是一个位状态控制器,第一位代表是否订阅行为被取消,第二位代表producer对应的sink和subscription行为是否被执行。
持有observableSink和subscribe产生的两个dispose,相当于对于observable和observer分别进行订阅取消操作
private var sink: Disposable?
private var subscription: Disposable?
dispose()方法充分体现了上述行为和结果
func dispose() {
let previousState = fetchOr(self.state, DisposeState.disposed.rawValue)
if (previousState & DisposeState.disposed.rawValue) != 0 {
return
}
if (previousState & DisposeState.sinkAndSubscriptionSet.rawValue) != 0 {
guard let sink = self.sink else {
rxFatalError("Sink not set")
}
guard let subscription = self.subscription else {
rxFatalError("Subscription not set")
}
sink.dispose()
subscription.dispose()
self.sink = nil
self.subscription = nil
}
}
AnonymousObservable AnonymouseObservableSink
回归之前UISwitch+Rx的实例
创建内部事件分发机制
由于UISwitch发布事件是通过用户行为ControlTarget,UISwitch.rx.ison是observable对象,因为需要使用匿名的observable去实现这一目的,
extension ObservableType {
// MARK: create
/**
Creates an observable sequence from a specified subscribe method implementation.
- seealso: [create operator on reactivex.io](http://reactivex.io/documentation/operators/create.html)
- parameter subscribe: Implementation of the resulting observable sequence's `subscribe` method.
- returns: The observable sequence with the specified implementation for the `subscribe` method.
*/
public static func create(_ subscribe: @escaping (AnyObserver<Element>) -> Disposable) -> Observable<Element> {
AnonymousObservable(subscribe)
}
}
observable.create这一通用的方法用于创建匿名observable来实现内置的事件发布逻辑。
final private class AnonymousObservable<Element>: Producer<Element> {
typealias SubscribeHandler = (AnyObserver<Element>) -> Disposable
let subscribeHandler: SubscribeHandler
init(_ subscribeHandler: @escaping SubscribeHandler) {
self.subscribeHandler = subscribeHandler
}
override func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element {
let sink = AnonymousObservableSink(observer: observer, cancel: cancel)
let subscription = sink.run(self)
return (sink: sink, subscription: subscription)
}
}
subscribeHandle是事件派发机制,而返回dispose就是这一机制的令牌。
业务触发订阅事件处理
当业务层调用订阅设定事件处理(Observer),Producer响应subscribe方法
override func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
if !CurrentThreadScheduler.isScheduleRequired {
// The returned disposable needs to release all references once it was disposed.
let disposer = SinkDisposer()
let sinkAndSubscription = self.run(observer, cancel: disposer)
disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)
return disposer
}
else {
return CurrentThreadScheduler.instance.schedule(()) { _ in
let disposer = SinkDisposer()
let sinkAndSubscription = self.run(observer, cancel: disposer)
disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)
return disposer
}
}
}
创建sinkDisposer,并调用子类的run()方法
AnonymousObservable调用run() ,生成AnonymousObservableSink封装订阅的Observer对象,并将sink和subscription的dispose传给sinkDisposer
关联
Producer, 响应业务层的subscribe(Observer),调用子类的run方法,持有sinkDisposer令牌,维持sink的生命周期
AnonymousObservable,匿名observable,通过subscribehandler触发observer.on的事件分派,例如UISwitch.rx.isOn,通过用户行为(ControlTarget)来产生事件分派,通过Observable.create创建。
AnonymousObservableSink,封装Producer subscribe的Observer对象,通过forwardon来控制Observer的订阅行为。
同样的设计原理应用在single,maybe等相关对象上。
另一个例子 Do DoSink Producer
public func `do`(onNext: ((Element) throws -> Void)? = nil, afterNext: ((Element) throws -> Void)? = nil, onError: ((Swift.Error) throws -> Void)? = nil, afterError: ((Swift.Error) throws -> Void)? = nil, onCompleted: (() throws -> Void)? = nil, afterCompleted: (() throws -> Void)? = nil, onSubscribe: (() -> Void)? = nil, onSubscribed: (() -> Void)? = nil, onDispose: (() -> Void)? = nil)
-> Observable<Element>
这个接口需要该Observable在不同的时机调用相应闭包实现相关逻辑。例如:
self.result = dispatcher
.do(onSubscribed: { weakDelegateProxy?.checkSelectorIsObservable(selector); weakDelegateProxy?.reset() }, onDispose: { weakDelegateProxy?.reset() })
.share()
.subscribe(on: mainScheduler)
这个例子说明dispatcher(observable)需要在onsubscribed和onDispose时进行相关delegateproxy的行为逻辑。
Do
Do是一种observable,继承于Producer
private let source: Observable<Element>
private let eventHandler: EventHandler
private let afterEventHandler: AfterEventHandler
private let onSubscribe: (() -> Void)?
private let onSubscribed: (() -> Void)?
private let onDispose: (() -> Void)?
source:相关observable对象
eventHandler:前置事件处理器
afterEventHandler:后置事件处理器
onSubscribe:订阅发生前
onSubscribed:订阅发生后
onDispose:订阅取消
这就意味着,Do这一类型的observable是需要额外控制这些时机加的逻辑处理
DoSink
Producer通过subscribe触发子类observable.run的运行,产生DoSink,用于封装Observer,
init(eventHandler: @escaping EventHandler, afterEventHandler: @escaping AfterEventHandler, observer: Observer, cancel: Cancelable) {
self.eventHandler = eventHandler
self.afterEventHandler = afterEventHandler
super.init(observer: observer, cancel: cancel)
}
DoSink封装observer.on用于控制整个订阅过程的所有时机的事件调用和事件的前转调用。
func on(_ event: Event<Element>) {
do {
try self.eventHandler(event)
self.forwardOn(event)
try self.afterEventHandler(event)
if event.isStopEvent {
self.dispose()
}
}
catch let error {
self.forwardOn(.error(error))
self.dispose()
}
}
分析
DoSink和AnonymousSink两者都是对Observer的封装,前者用于在observer事件响应过程中在合适的时机回调相应eventHandler,后者用于在observer订阅后,通过subscribeHandler生成相应的anonymousObservable对象。
基本上这类observable->Producer->ObservableSink->Observer的设计链路都是为了控制生成时机和事件处理时机而进行的。
但有一个do的重要特点,注意run方法内容:
override func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element {
....
let subscription = self.source.subscribe(sink)
....
订阅对象都是在调用do方法的source上的,意思就是do只是当前observable的一种行为模式,生成一个do也可以用于observable。这个在publishSubject的实现上有明显的作用.