RxSwift Observable 源码分析

96
iTMMT
2016.10.13 12:00* 字数 1097

魔法

一开始使用 RxSwift 的时候,感觉就像是看到了魔法,神奇的 Observable 各种变换, Event 在代码中乱射。
一个早上,没有咖啡,我打开了 RxSwift 的源码,掉入深坑。
在我读了几遍代码之后,打算搞清楚一个小片段代码背后的故事,Object Map 是什么样的,一个完整的生命周期是什么样的?

小目标

额,最后搞清楚下面这段小代码背后里的小乾坤。

import RxSwift
let subscription = Observable<String>.create { o -> Disposable in
        o.onNext("Hello")
        return Disposables.create {
            print("hello")
        }
    }
.subscribe(onNext: {
       print($0)
    })

subscription.dispose()

在此之前,我们一步一步去分析。

let anonymousObservable = Observable<String>.create { o -> Disposable in
        o.onNext("Hello")
        return Disposables.create {
            print("hello")
        }
    }

这只是简单的创建了一个 AnonymousObservable,参数就是 Observable<String>.create 后面跟上的 closure.

// RxSwift 源码
extension Observable {
    // 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.
    */
    // @warn_unused_result(message:"http://git.io/rxs.uo")
    public static func create(_ subscribe: @escaping (AnyObserver<E>) -> Disposable) -> Observable<E> {
        return AnonymousObservable(subscribe)
    }

然后进入 AnonymousObservable 内部去瞧瞧。

class AnonymousObservable<Element> : Producer<Element> {
    typealias SubscribeHandler = (AnyObserver<Element>) -> Disposable

    let _subscribeHandler: SubscribeHandler

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

    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)
    }
}

<a href="#_subscribeHandler"></a> 看一看出之前的 closure 参数赋值给了 _subscribeHandler, 另外有一个 run 方法,目前不知道做什么的,我们可以去 AnonymousObservable 父类的 Producer 去看看

class Producer<Element> : Observable<Element> {
    override init() {
        super.init()
    }
    
    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
            }
        }
    }
    
    func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element {
        abstractMethod()
    }
}

父类是一个 Observable, 有一个 subscribe 方法,就是在我们对一个 Observable 进行订阅的时候调用的。
我们先走 subscribe 方法内部 !CurrentThreadScheduler.isScheduleRequired 这条路径。可以看到返回的一个disposer: SinkDisposer,而且把这个 disposer 和 我们的 observer 当作参数去调用了 run, 一看可知, 调用的 run 其实是 AnonymousObservable 实现的 run 方法,


class AnonymousObservable<Element> : Producer<Element> {
    typealias SubscribeHandler = (AnyObserver<Element>) -> Disposable

    let _subscribeHandler: SubscribeHandler

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

    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)
    }
}

run 方法内部使用我们之前提供的 observer 和 <a href="#disposer"></a>disposer: SinkDIsposer,创建了一个 AnonymousObservableSink


class AnonymousObservableSink<O: ObserverType> : Sink<O>, ObserverType {
    typealias E = O.E
    typealias Parent = AnonymousObservable<E>

    // state
    private var _isStopped: AtomicInt = 0

    override init(observer: O, cancel: Cancelable) {
        super.init(observer: observer, cancel: cancel)
    }

    func on(_ event: Event<E>) {
        switch event {
        case .next:
            if _isStopped == 1 {
                return
            }
            forwardOn(event)
        case .error, .completed:
            if AtomicCompareAndSwap(0, 1, &_isStopped) {
                forwardOn(event)
                dispose()
            }
        }
    }

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

可以看出,这个 Sink 实现了 ObserverType, 它是一个 observer,
AnonymousObservable run 方法紧接着调用了 sink.run,把自己当作参数传入,
sink.run 方法把 sink 封装成一个 AnyOberver, 这种 TypeEraser 模式很常见,
使用 AnonymousObservable 的 _subscribeHandler
记得 _subscribeHandler 是一个 closure, 这样这个 _subscribeHandler 便capture 了这个 sink, 把这个 sink 充当了 observer。

sink.run 返回的是一个disposable

return Disposables.create {
            print("hello")
        }

把这个 sink 和 sink.sun 返回的 disposable 赋值给了之前的 disposer

这时候,我们可以画出 Observable, Sink, disposer 之间的关系图

关系图1

然而,subscribe(onNext:) 的源码告诉我们,

//  ObservableType+Extensions.swift

    // @warn_unused_result(message: "http://git.io/rxs.ud")
    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> { e in
            switch e {
            case .next(let value):
                onNext?(value)
            case .error(let e):
                onError?(e)
                disposable.dispose()
            case .completed:
                onCompleted?()
                disposable.dispose()
            }
        }
        return Disposables.create(
            self.subscribeSafe(observer),
            disposable
        )
    }

可以看到我们返回的是一个 BinaryDisposable,上面的 subscription 只是这个 BinaryDisposable 两个 disposable 的一个,另一个是 Nop(no operation) Disposable。从代码中可以看到,subscribe(onNext:) 首先将 onNext 封装成一个 AnyObserver, 然后再去订阅这个封装了 onNext 的 AnyObserver。
因此修改后的关系图如下,

关心图2
Event 的流通路径

应该不难看出来,Observable 在有新的事件 Event 时,首先传给 AnyObserver(封装sink), 然后这个 sink 把 event 传递给了 AnyObserver(封装onNext)。
我们可以尝试画一下下面代码的关系图,和 Event 的流通路径。

import RxSwift
let subscription = Observable<String>.create { o -> Disposable in
        o.onNext("Hello")
        return Disposables.create {
            print("hello")
        }
    }
.map {
      return $0.characters.count 
}
.subscribe(onNext: {
       print($0)
    })

subscription.dispose()

这里仅给出 Event 流动顺序
AnonymousObservable -> AnonymousObservableSink -> MapSInk -> Observer

其实,在诸如操作符 map, flatMap, subscribeOn 对一个 Observable 操作时,只是生成了一个 Sink, 安插在 Observable 和 Observer 中间,Sink 可以对 Observable 产生的 Event 携带的 Value/Error 进行转换操作,比如利用 map 后面跟的 closure 对 Event 的 value 进行处理,对 Error 不做处理, 然后传递给 Observer, 当然也有针对 Error 进行处理的操作符,比如 catch*。

生命周期

回到我们最初的代码

import RxSwift
let subscription = Observable<String>.create { o -> Disposable in
        o.onNext("Hello")
        return Disposables.create {
            print("hello")
        }
    }
.subscribe(onNext: {
       print($0)
    })

subscription.dispose()

分析一下在 subscription.dispose() 是发生了什么?
我们已经分析过,这里的 subscription 是一个 BinaryDisposable, BinaryDisposable 的 dispose 长这样。

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

就是保证 dispose 掉自己的两个 disposable, 通过 subscribe(onNext:) 的源码我们知道,_disposable2 是一个 Nop, _disposable1 就是下图中的 C, _disposable1 是 B

关系图3
<a name="dispose"> Dispose</a>

A dispose
   C dispose
     D dispose
         C dispose
     E dispose
     4 & 5 消失
     E 被 deallocate
   B dispose
1 &2 消失
B & C 被 deallocate

当 Observable 和 BinaryDisposable 所在的作用域消失时,所有剩下的对象都将被销毁。

下图红色的表示取消的引用和被 dellocate 的对象


消失.png

从图中我们可以看出,在调用 dispose 的时候,Observable 和 Observer 都继续存活的,不是 deallocate。 在subscription dipose 之后,Sink 将不再传递 Event ,即使之前并没有收到 Event(.completed) 或者 Event(error)。

// sink.swift 
   final func forwardOn(_ event: Event<O.E>) {
        if _disposed {
            return
        }
        _observer.on(event)
    }

破除引用环和循环调用

引用环

同时注意到图中C 和 D 的引用环如何破除

C 和 D 的循环调用如何破除

//  Sink.swift
   func dispose() {
        _disposed = true
        _cancel.dispose()
    }
// SinkDisposer
   func dispose() {
        #if os(Linux)
        _lock.lock(); defer { _lock.unlock() }
        let previousState = Int32(_state)
        _state = _state | DisposeState.disposed.rawValue
        #else
        let previousState = OSAtomicOr32OrigBarrier(DisposeState.disposed.rawValue, &_state)
        #endif
        if (previousState & DisposeStateInt32.disposed.rawValue) != 0 {
            return
        }

        if (previousState & DisposeStateInt32.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 这个问题应该不难解决。

Rxswift
Web note ad 1