RxSwift核心流程解析

314 阅读6分钟

概括

RxSwift核心角色有‘可观察的序列’、‘观察者’、‘可释放资源’。为便于表达分别用‘Observables’、‘Observers’、‘Disposables’代替。

各个角色的功能不再描述。

8b1QQ1.png

RxSwift中最核心的流程为上图所描述的序列构建、订阅、发送事件、资源管理。

核心流程

下面是一个简单的使用可观察序列的例子。

/// 1
let subscribe: (AnyObserver<String>) -> Disposable = { observer in
            observer.onNext(“123”)
            return Disposables.create {
                debugPrint(“subscribe — dispose”)
            }
        }

/// 2
let observable = Observable<String>.create(subscribe)

/// 3
let disposable = observable.subscribe(onNext: { (value) in
            debugPrint(value)
        }, onError: { (error) in
            debugPrint(error)
        }, onCompleted: {
            debugPrint("onCompleted")
        }) {
            debugPrint("onDisposed")
        }

/// 4
disposable.disposed(by: rx.disposeBag)

/// 5
observable.subscribe(onNext: { (value) in
            debugPrint(“subscribe2: \(value)”)
        }, onError: { (error) in
            debugPrint(“subscribe1: \(error)”)
        }, onCompleted: {
            debugPrint("subscribe1: onCompleted")
        }) {
            debugPrint("subscribe1: onDisposed")
        }.disposed(by: rx.disposeBag)
  • ‘1’:描述事件产生的过程并返回一个可释放资源
  • ‘2’:构建序列
  • ‘3’:订阅序列
  • ‘4’:管理上述过程产生的资源(以ARC的形式)

通过调试以上代码,控制台打印以下输出:

  • 进入页面时
”onNext: 123”
”subscribe1: 123”
”onNext: 123”
”subscribe2: 123”
  • 离开页面时
”subscribe — dispose”
”subscribe1: onDisposed”
”subscribe — dispose”
”subscribe2: onDisposed”

依据以上输出,可以看到:

  1. 每次序列被订阅时,都会调用‘1’方法,然后调用相应subscribe函数中的onNext方法

  2. 序列被观察者订阅所产生的Disposable被释放时,‘1’中的可释放资源被调用,同时subscribe函数中的onDisposed方法也会被调用。

对以上结论分两个步骤分别来解释。

序列构建、订阅、发送事件、观察者响应

针对该过程的流程图如下:

8b1ImV.png

这里又分为两个流程:1、序列的构建; 2、序列订阅(在这里序列发送事件,观察者进行响应)。

序列的构建

1、Observable调用扩展协议ObservableType中的’create’方法,以‘1’为入参,返回一个Observable。

public static func create(_ subscribe: @escaping(AnyObserver<E>) -> Disposable) -> Observable<E> {
        return AnonymousObservable(subscribe)
    }

2、生成AnonymousObservable实例,并保存‘1’到常量_subscribeHandler

init(_ subscribeHandler: @escaping SubscribeHandler) {
        _subscribeHandler = subscribeHandler
    }

序列订阅

1、调用ObservableType+Extensions中的subscribe方法

public func subscribe(onNext: ((E) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)
        -> Disposable {
            let disposable: Disposable
            
            if let disposed = onDisposed {
                disposable = Disposables.create(with: disposed)
            }
            else {
                disposable = Disposables.create()
            }
            
            #if DEBUG
                let synchronizationTracker = SynchronizationTracker()
            #endif
            
            let callStack = Hooks.recordCallStackOnError ? Hooks.customCaptureSubscriptionCallstack() : []
            
            let observer = AnonymousObserver<E> { event in
                
                #if DEBUG
                    synchronizationTracker.register(synchronizationErrorMessage: .default)
                    defer { synchronizationTracker.unregister() }
                #endif
                
                switch event {
                case .next(let value):
                    onNext?(value)
                case .error(let error):
                    if let onError = onError {
                        onError(error)
                    }
                    else {
                        Hooks.defaultErrorHandler(callStack, error)
                    }
                    disposable.dispose()
                case .completed:
                    onCompleted?()
                    disposable.dispose()
                }
            }
            return Disposables.create(
                self.asObservable().subscribe(observer),
                disposable
            )
    }

在该函数中把对元素、错误、完成、释放的响应封装到AnonymousObserver类型中。

2、动态调用AnonymousObservable的父类Producer中的订阅方法。Producer重写了父类Observable中的方法。

override func subscribe<O : ObserverType>(_ observer: O) -> Disposable where O.E == Element {
        if !CurrentThreadScheduler.isScheduleRequired {
            // The returned disposable needs to release all references once it was disposed.
            let disposer = SinkDisposer()
            let sinkAndSubscription = 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
            }
        }
    }

在该方法中又会调用到了run方法

3、调用AnonymousObservablerun方法。因为重写了父类中的方法。

override func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element {
        let sink = AnonymousObservableSink(observer: observer, cancel: cancel)
        let subscription = sink.run(self)
        return (sink: sink, subscription: subscription)
    }

4、调用AnonymousObservableSink中的run方法

func run(_ parent: Parent) -> Disposable {
        return parent._subscribeHandler(AnyObserver(self))
    }

5、序列创建时的函数即‘1’被调用,所以”onNext: 123”会被打印。

6、再回到AnonymousObservablerun方法中,AnonymousObservableSink的初始化函数调用父类的方法,并把1中封装的AnonymousObserver保存到常量_observer中。

7、在4中调用1的函数时入参数为AnyObserver(self)。由于AnonymousObservableSink遵守了ObserverType协议,所以AnyObserver调用了如下的构造函数:

public init<O : ObserverType>(_ observer: O) where O.E == Element {
        self.observer = observer.on
    }

在该方法中常量observer引用了AnonymousObservableSinkon函数:

func on(_ event: Event<E>) {
        #if DEBUG
            _synchronizationTracker.register(synchronizationErrorMessage: .default)
            defer { _synchronizationTracker.unregister() }
        #endif
        switch event {
        case .next:
            if _isStopped.load() == 1 {
                return
            }
            forwardOn(event)
        case .error, .completed:
            if _isStopped.fetchOr(1) == 0 {
                forwardOn(event)
                dispose()
            }
        }
    }

8、当AnyObserver发送事件时也就调用了AnonymousObservableSinkon函数。

public func on(_ event: Event<Element>) {
        return self.observer(event)
    }

9、发送事件给观察者。

AnonymousObservableSink中的on中的forwardOn被调用。

final func forwardOn(_ event: Event<O.E>) {
        #if DEBUG
            _synchronizationTracker.register(synchronizationErrorMessage: .default)
            defer { _synchronizationTracker.unregister() }
        #endif
        if _disposed {
            return
        }
        _observer.on(event)
    }

至此,序列被订阅时的响应事件的方法分别会被调用。

资源管理

资源的管理分为两部分:生成、持有/释放。

总的流程如下图:

8qfRWF.png

为易于理解,该部分先讲后半部分。

Disposable持有/释放

1、该例子中的DisposeBag实例运行时自动生成,关联到vc。

public var disposeBag: DisposeBag {
        get {
            return synchronizedBag {
                if let disposeObject = objc_getAssociatedObject(base, &disposeBagContext) as? DisposeBag {
                    return disposeObject
                }
                let disposeObject = DisposeBag()
                objc_setAssociatedObject(base, &disposeBagContext, disposeObject, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
                return disposeObject
            }
        }
        
        set {
            synchronizedBag {
                objc_setAssociatedObject(base, &disposeBagContext, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            }
        }
    }

2、DisposeBag

主要有如下方法和属性:

  • _disposables变量:[Disposable],存有可释放资源
  • insert方法:新增可释放资源
public func insert(_ disposable: Disposable) {
        _insert(disposable)?.dispose()
    }
    
    private func _insert(_ disposable: Disposable) -> Disposable? {
        _lock.lock(); defer { _lock.unlock() }
        if _isDisposed {
            return disposable
        }

        _disposables.append(disposable)

        return nil
    }
  • dispose方法:遍历可释放资源调用dispose方法。
private func dispose() {
        let oldDisposables = _dispose()

        for disposable in oldDisposables {
            disposable.dispose()
        }
    }

    private func _dispose() -> [Disposable] {
        _lock.lock(); defer { _lock.unlock() }

        let disposables = _disposables
        
        _disposables.removeAll(keepingCapacity: false)
        _isDisposed = true
        
        return disposables
    }

3、Disposable通过disposed方法交由DisposeBag实例管理生命周期。

public func disposed(by bag: DisposeBag) {
        bag.insert(self)
    }

Disposable创建

本例中序列被订阅时subscribe函数返回BinaryDisposable实例,交由DisposeBag管理。

 public func subscribe(onNext: ((E) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)
        -> Disposable {
            let disposable: Disposable
            if let disposed = onDisposed {
                disposable = Disposables.create(with: disposed)
            }
            else {
                disposable = Disposables.create()
            }            
            let observer = AnonymousObserver<E> { event in
                switch event {
                case .next(let value):
                    onNext?(value)
                case .error(let error):
                    if let onError = onError {
                        onError(error)
                    }
                    else {
                        Hooks.defaultErrorHandler(callStack, error)
                    }
                    disposable.dispose()
                case .completed:
                    onCompleted?()
                    disposable.dispose()
                }
            }
            return Disposables.create(
                self.asObservable().subscribe(observer),
                disposable
            )
    }

1、AnonymousDisposable

序列被订阅时onDisposed函数不为nil,onDisposed当作入参生成一个AnonymousDisposable实例。

其实现了Disposable协议。

let disposable: Disposable
            if let disposed = onDisposed {
                disposable = Disposables.create(with: disposed)
            }
extension Disposables {
    public static func create(with dispose: @escaping () -> ()) -> Cancelable {
        return AnonymousDisposable(disposeAction: dispose)
    }
}

onDisposed被存储在AnonymousDisposable_disposeAction变量中,并在dispose调用时调用。

fileprivate init(disposeAction: @escaping DisposeAction) {
        _disposeAction = disposeAction
        super.init()
    }
fileprivate func dispose() {
        if _isDisposed.fetchOr(1) == 0 {
            assert(_isDisposed.load() == 1)

            if let action = _disposeAction {
                _disposeAction = nil
                action()
            }
        }
    }

2、SinkDisposer

如上subscribe方法所示:

self.asObservable().subscribe(observer)

2.1以响应序列事件的函数为入参生成的观察者AnonymousObserver为参生成

SinkDisposer实例。动态派发调用父类Producer的订阅方法。

override func subscribe<O : ObserverType>(_ observer: O) -> Disposable where O.E == Element {
        if !CurrentThreadScheduler.isScheduleRequired {
            // The returned disposable needs to release all references once it was disposed.
            let disposer = SinkDisposer()
            let sinkAndSubscription = 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实例。

2.2 AnonymousObservablerun函数被调用时生成

AnonymousObservableSink实例,AnonymousObservableSink实例又调

run方法,最终调用AnonymousObservable的常量

_subscribeHandler返回Disposable,赋值给SinkDisposer的变量

_subscription

let sinkAndSubscription = self.run(observer, cancel: disposer)

override func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element {
        let sink = AnonymousObservableSink(observer: observer, cancel: cancel)
        let subscription = sink.run(self)
        return (sink: sink, subscription: subscription)
    }
func run(_ parent: Parent) -> Disposable {
        return parent._subscribeHandler(AnyObserver(self))
    }
disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)

即序列构造中的入参返回的Disposable变量(即核心流程中的‘/ 1’),由SinkDisposer中的_subscription变量引用。

2.3 SinkDisposer类遵守并实现了Disposabledispose方法。

func dispose() {
        let previousState = _state.fetchOr(DisposeState.disposed.rawValue)

        if (previousState & DisposeState.disposed.rawValue) != 0 {
            return
        }

        if (previousState & DisposeState.sinkAndSubscriptionSet.rawValue) != 0 {
            guard let sink = _sink else {
                rxFatalError("Sink not set")
            }
            guard let subscription = _subscription else {
                rxFatalError("Subscription not set")
            }

            sink.dispose()
            subscription.dispose()

            _sink = nil
            _subscription = nil
        }
    }

dispose函数被调用时_subscription变量的dispose函数被点用,即执行debugPrint(“subscribe — dispose”)

3、BinaryDisposable

序列的subscribe方法中,以AnonymousDisposable

SinkDisposer为参数构造并返回。

Disposables.create(
                self.asObservable().subscribe(observer),
                disposable
            )
public static func create(_ disposable1: Disposable, _ disposable2: Disposable) -> Cancelable {
        return BinaryDisposable(disposable1, disposable2)
    }
init(_ disposable1: Disposable, _ disposable2: Disposable) {
        _disposable1 = disposable1
        _disposable2 = disposable2
        super.init()
    }

BinaryDisposable实现了Disposable协议中的dispose方法,在被调用时调用持有的Disposable变量。

func dispose() {
        if _isDisposed.fetchOr(1) == 0 {
            _disposable1?.dispose()
            _disposable2?.dispose()
            _disposable1 = nil
            _disposable2 = nil
        }
    }

即订阅方法中的onDisposed函数和{ debugPrint(“subscribe — dispose”)}函数被调用。