RxSwift细节(一)Observable Sink Producer

本文详细解释了Observable、Producer和Sink在Reactive编程中的作用,特别是如何通过Producer控制订阅时机,以及Sink负责事件处理和取消订阅。还介绍了AnonymousObservable和Do的相关概念,强调了它们在事件触发和控制时机方面的灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考文档

observable类型细分

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的实现上有明显的作用.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值