RxSwift 源码剖析

167 阅读10分钟

首先,让我们忘掉什么 Observable, Observer, 直接回归问题的本质。

基本需求: viewModel 里的一个网络请求,服务端下发一组数据,viewController 里收到正确数据,刷新UI。

如果没有RxSwift,代码可能是这样的:

func request(_ success: @escaping ((String) -> ())) {
    // 假设这是一个网络请求
    DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
        success("我是一条数据")
    }
}
--------------
// vc 中就是这样的
viewModel.request { data in
    print(data)
}

问题是,如果我有多个UI状态变更需要这组数据,且这些变更毫不相关,那在vc 里面是不是要多次调用 request方法? 这时候我们可能会写出这样的代码

var dataHandler1: ((String) -> Void)?
var dataHandler2: ((String) -> Void)?
var dataHandler3: ((String) -> Void)?
// request 变成了这样
func request() {
    // 假设这是一个网络请求
    DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
        self.dataHandler1?("我是一条数据")
        self.dataHandler2?("我是一条数据")
        self.dataHandler3?("我是一条数据")
    }
}
--------------
// vc 中变成了这样
viewModel.dataHandler1 = { data in
    // 执行UI1状态变更
}
viewModel.dataHandler2 = { data in
    // 执行UI2状态变更
}
...

这样太丑了,这些笨重的 handler 做的事差不多是一样的,为什么不把他们放到一个数组统一处理?另外,viewModel 只是负责提供请求数据的,他根本不需要知道究竟有多少个 handler,每一个 handler 具体做了什么。 所以,我们应该自己封装一个 handler 的管理类,这个类里面存放了一组 handler,并且每一次网络请求成功回调后,执行所有的 handler。

一个最简单的事件序列,大概就是这样的:

// 传入的事件类型,先暂时忽略 error, completed 等类型
// 这里只关注 next 事件
enum TestEvent<Element> {
    case next(Element)
}

class TestSubject<Element> {
    // handler 事件变成了 Observer
    typealias Observer = (TestEvent<Element>) -> Void
    
    init() {
        
    }
    // 存放 Observer 的数组
    var observers: [Observer] = []
    // on 被调用,事件产生,遍历 observers, 执行每一个 observer
    func on(_ event: TestEvent<Element>) {
        dispatch(event)
    }
    // 只要新增一个 observer,就把他加入到事件序列里
    func subscribe(_ observer: @escaping Observer) {
        observers.append(observer)
    }
    // 清空事件序列,清空之后,之前添加的 observer 全部失效,但是不耽误
    // 之后的 observer 添加,之后会聊到 DisposeBag 的实现机制
    func dispose() {
        observers.removeAll()
    }
    
    private func dispatch(_ event: TestEvent<Element>) {
        observers.forEach {
            $0(event)
        }
    }
}

这样,viewModel 和 vc 的代码变得更加清晰和可维护,对于vc中的UI状态管理也更加统一

// ViewModel
let testSubject = TestSubject<String>()

func request() {
    let timer = Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
    timer.subscribe(onNext: { [weak self] time in
        self?.testSubject.on(.next("发射"))
    }).disposed(by: bag)
}
-----------
// vc
viewModel.testSubject.subscribe { event in
    if case let .next(element) = event {
        print("observer1 --- \(element)")
    }
}
viewModel.testSubject.subscribe { event in
    if case let .next(element) = event {
        print("observer2 --- \(element)")
    }
}

像 TestSubject 这样既可以作为观察者产生事件,又可以作为被观察者处理事件的,在 RxSwift里,可以参考 PublishSubject,BehaviorSubject

现实世界的 Observable, Observer 和 Disposable

让我们从一个 Observable的创建,订阅,和销毁逐步分析

let testObservable = Observable<String>.create { 
    observer -> Disposable in
    observer.onNext("1111")
    return Disposables.create {
        print("销毁了")
    }
}
let testDisposable = testObservable.subscribe(onNext: { value in
    print(value)
})
    
testDisposable.disposed(by: bag)

首先我们思考三个问题:

  1. creat 闭包内容是何时被调用的?
  2. subscribe 方法的 onNext 事件是何时被调用的?
  3. Dsiposable 是何时清除不再需要的资源的?

第一个问题: creat 闭包内容是何时被调用的?

首先看一下 creat 函数

extension ObservableType {
    public static func create(_ subscribe: @escaping (AnyObserver<Element>) -> Disposable) -> Observable<Element> {
        AnonymousObservable(subscribe)
    }
}
// 函数是一个 以 AnyObserver 作为参数,以 Disposable 作为返回值的闭包,返回值就是一个 Observable
// 函数内返回了一个 AnonymousObservable

下面看一下 AnonymousObservable 到底做了什么

final private class AnonymousObservable<Element>: Producer<Element> {
    typealias SubscribeHandler = (AnyObserver<Element>) -> Disposable
    // 首先,把 creat 函数传进来的 闭包 作为一个存储属性保存了下来
    let subscribeHandler: SubscribeHandler
    // 保存闭包
    init(_ subscribeHandler: @escaping SubscribeHandler) {
        self.subscribeHandler = subscribeHandler
    }
    // 其次是一个 run 函数继承自父类,run 函数何时被调用不清楚,只能查看父类
    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)
    }
}

AnonymousObservable 是 Observable的子类,继承关系是: AnonymousObservable -> Producer -> Observable -> ObservableType -> ObservableConvertibleType

接着,我们查看一下 Producer(为了方便阅读代码,我会把源码中和事件逻辑不相关的全部删掉,如果对源码感兴趣,可以自行查阅)

class Producer<Element>: Observable<Element> {
    override init() {
        super.init()
    }

    override func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
       let disposer = SinkDisposer()
       // 我们只需要关注这一行即可
       let sinkAndSubscription = self.run(observer, cancel: disposer)
       disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)
       return disposer
    }
    // AnonymousObservable 重写的就是这个方法,忽略父类的run,直接分析
    // AnonymousObservable 的 run 函数即可
    func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element {
        rxAbstractMethod()
    }
}

因为 Producer 继承自 Observable,遵守了 ObservableType 协议,所以它实现了 subscribe 方法,subscribe 方法调用了子类 AnonymousObservable 的 run 方法(一定要记住这里 run 的调用时机,待会儿会回来解释)。 那么,subscribe 方法又是在何时调用的呢? 来到 ObservableType+Extensions.swift 文件

extension ObservableType {

    public func subscribe(
        onNext: ((Element) -> 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<Element> { event in
                
                switch event {
                case .next(let value):
                    onNext?(value)
                case .error(let error):
                    onError?(error)
                    disposable.dispose()
                case .completed:
                    onCompleted?()
                    disposable.dispose()
                }
            }
            return Disposables.create(
                self.asObservable().subscribe(observer),
                disposable
            )
    }
}

当testObservable 调用了 subscribe 函数后

testObservable.subscribe(onNext: { value in
    print(value)
})

函数内部帮我们创建了一个 AnonymousObserver对象,在初始化时传递进来一个闭包,并持有这个闭包_eventHandler,AnonymousObserver是匿名观察者,用于存储,和处理事件。 然后来到本函数的核心代码

self.asObservable().subscribe(observer)

还记得Producer的 subscribe 函数吗?self.asObservable返回的是 Producer对象自己,Producer的subscribe 函数就是在这里调用的!然后这里执行了Producer的子类 AnonymousObservable 的 run 函数。再回到 run 函数

override func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) 
-> (sink: Disposable, subscription: Disposable) 
where Observer.Element == Element {
        let sink = AnonymousObservableSink(observer: observer, cancel: cancel)
        // AnonymousObservableSink的 run 函数往后看
        let subscription = sink.run(self)
        return (sink: sink, subscription: subscription)
    }

AnonymousObservableSink 是专门为 AnonymousObservable而服务的 sink,sink 可以理解成管道,是将Observable的事件传递给Observer的桥梁。(后面几乎所有继承自Observable的特殊类型都是这么设计的)

final private class AnonymousObservableSink<Observer: ObserverType>: Sink<Observer>, ObserverType {
    typealias Element = Observer.Element 
    typealias Parent = AnonymousObservable<Element>

    // state
    private let isStopped = AtomicInt(0)

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

    func on(_ event: Event<Element>) {
        switch event {
        case .next:
            if load(self.isStopped) == 1 {
                return
            }
            self.forwardOn(event)
        case .error, .completed:
            if fetchOr(self.isStopped, 1) == 0 {
                self.forwardOn(event)
                self.dispose()
            }
        }
    }

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

AnonymousObservableSink 的 run 函数真正调用了AnonymousObservable 所持有的 subscribeHandler,同时给闭包传入了一个 AnyObserver(self)(AnyObserver的初始化方法,参数是一个遵守了 ObserverType 协议的类型,也就是AnonymousObservableSink自己),还记得 subscribeHandler 是什么吗?没错,是creat函数的参数,闭包内容是在这里被执行的,也就是下面的代码

let testObservable = Observable<String>.create { 
    observer -> Disposable in
    observer.onNext("1111")
    return Disposables.create {
        print("销毁了")
    }
}

可以看到,此时此刻,observer 的 onNext 方法被执行了,这个observer就是刚刚那个 AnyObserver(self)。至此,我们解决了第一个问题: "creat 闭包内容是何时被调用的?"

第二个问题:subscribe 方法的 onNext事件是何时被调用的?

接下来,我们应该着眼于 AnyObserver 的初始化方法

public struct AnyObserver<Element> : ObserverType {
    public typealias EventHandler = (Event<Element>) -> Void
    private let observer: EventHandler

    public init(eventHandler: @escaping EventHandler) {
        self.observer = eventHandler
    }
    
    // 外面的 “AnyObserver(self)”就是调用的这个方法
    public init<Observer: ObserverType>(_ observer: Observer) where Observer.Element == Element {
        // 这里比较绕,需要仔细想一想
        // AnyObserver(self)传进来的 observer 是 AnonymousObservableSink对象
        // 这句代码的意思是把 AnonymousObservableSink 的 on 方法传给了
        // observer 变量,因为这个 observer 本身是一个 (Event<Element>) -> Void 类型,
        // AnonymousObservableSink 的 on 方法本质上也是 (Event<Element>) -> Void 类型
        self.observer = observer.on
    }
    // observer.onNext("")执行后,执行这个方法,具体定义参照 ObserverType 的代码
    // on 方法直接执行了 observer 这个闭包代码(千万别忘了 observer 其实就是 AnonymousObservableSink 的 on 方法)
    public func on(_ event: Event<Element>) {
        self.observer(event)
    }

    public func asObserver() -> AnyObserver<Element> {
        self
    }
}

当 creat 闭包中的 observer.onNext("")执行后,会来到 AnyObserver 的 on 方法,参照 ObserverType 这个协议中的定义(不管是 onNext, onCompleted 还是 onError 都是直接调用了 on 方法)

public protocol ObserverType {
    associatedtype Element

    func on(_ event: Event<Element>)
}
extension ObserverType {
    public func onNext(_ element: Element) {
        self.on(.next(element))
    }
    
    public func onCompleted() {
        self.on(.completed)
    }
    
    public func onError(_ error: Swift.Error) {
        self.on(.error(error))
    }
}

此时的 on 方法,正是 AnonymousObservableSink 的 on 方法,代码如下

final private class AnonymousObservableSink<Observer: ObserverType>: Sink<Observer>, ObserverType {

    func on(_ event: Event<Element>) {
        switch event {
        case .next:
            if load(self.isStopped) == 1 {
                return
            }
            self.forwardOn(event)
        case .error, .completed:
            if fetchOr(self.isStopped, 1) == 0 {
                self.forwardOn(event)
                self.dispose()
            }
        }
    }

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

这个方法调用了父类 Sink 的 forwardOn 函数,forwardOn 函数真正调用了我们 subscribe 方法内生成的那个 AnonymousObserver(匿名监听者)的 on 方法。 而 event 参数就是 creat 函数内的 onNext 事件。

class Sink<Observer: ObserverType>: Disposable {
    // ...
    final func forwardOn(_ event: Event<Observer.Element>) {
        if isFlagSet(self.disposed, 1) {
            return
        }
        self.observer.on(event)
    }
}

目前为止,我们追到了 AnonymousObserver的 on 方法,AnonymousObserver 没有 on 方法,只有一个 onCore 方法,继续去父类 ObserverBase 找, 父类的 on 方法调用了子类onCore,onCore 调用了 eventHandler,并且把 上一步 forwardOn方法传入的 event 传进了闭包。

final class AnonymousObserver<Element>: ObserverBase<Element> {
    typealias EventHandler = (Event<Element>) -> Void
    
    private let eventHandler : EventHandler
    
    init(_ eventHandler: @escaping EventHandler) {
        self.eventHandler = eventHandler
    }

    override func onCore(_ event: Event<Element>) {
        self.eventHandler(event)
    }
}

class ObserverBase<Element> : Disposable, ObserverType {
    private let isStopped = AtomicInt(0)

    func on(_ event: Event<Element>) {
        switch event {
        case .next:
            // 暂时忽略 load 和 fetchOr 这样的判断方法
            // 他们与observer的调用逻辑无关
            if load(self.isStopped) == 0 {
                self.onCore(event)
            }
        case .error, .completed:
            if fetchOr(self.isStopped, 1) == 0 {
                self.onCore(event)
            }
        }
    }

    func onCore(_ event: Event<Element>) {
        rxAbstractMethod()
    }

    func dispose() {
        fetchOr(self.isStopped, 1)
    }
}

AnonymousObserver 的 eventHandler 不就是最初 ObservableType 拓展中的 subscribe 方法内生成的 AnonymousObserver 的初始化参数吗!

public func subscribe(
        onNext: ((Element) -> 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<Element> { event in
                //上面的 eventHandler被执行, 其实就是调用了这个代码块
                switch event {
                case .next(let value):
                    // 到这里,才真正的调用了我们最外层的 
                    // subscribe(onNext: { // 收到信号后... })
                    onNext?(value)
                case .error(let error):
                    if let onError = onError {
                        onError(error)
                    }
                    // error 或者 completed 发出
                    // 资源立即被释放
                    disposable.dispose()
                case .completed:
                    onCompleted?()
                    disposable.dispose()
                }
            }
            return Disposables.create(
                self.asObservable().subscribe(observer),
                disposable
            )
    }

至此,我们解决了第二个问题: "subscribe 方法的 onNext事件是何时被调用的"。

追踪Observable的订阅过程也在侧面验证了两个问题: 第一: 每增加一个Observer,Observable的creat方法的闭包就会被调用一次,联想到 share 操作符,共享事件结果。(造成的负面影响,如果有多个订阅,附加操作会被调用多次) 第二: 如果没有Observer来订阅 Observable,creat 方法的闭包是不会被执行的。

第三个问题: Dsiposable 是何时清除不再需要的资源的?

  • 一般的,序列如果发出了 error 或者 completed 事件,所有内部资源都会被释放,不需要我们手动释放(这个在前面 ObservableType+Extensions.swift 的subscribe 方法里面多次提到了)
  • 如果我们需要提前释放这些资源或取消订阅的话,那我们可以对返回的 Disposable 调用 dipose 方法
  • 官方推荐使用 DisposeBag,来管理订阅的生命周期,一般是把资源加入到一个全局的 DisposeBag 里面,它跟随着页面的生命周期,当页面销毁时 DisposeBag 也会随之销毁,同时 DisposeBag 里面的资源也会被一一释放。

由于时间关系,dispose 方法具体是如何执行的,本次分享就不再深入追踪源码了。我们只看一下常用的 DisposeBag 具体是怎么实现的。

extension Disposable {
    // 把当前disposabel加入到一个bag
    public func disposed(by bag: DisposeBag) {
        bag.insert(self)
    }
}

// DisposeBase 不需要关心(资源调试用的)
public final class DisposeBag: DisposeBase {
    
    private var lock = SpinLock()
    
    // 存放着所有被添加进来的 Disposable
    private var disposables = [Disposable]()
    private var isDisposed = false

    public override init() {
        super.init()
    }

    public func insert(_ disposable: Disposable) {
        self._insert(disposable)?.dispose()
    }
    
    private func _insert(_ disposable: Disposable) -> Disposable? {
        self.lock.performLocked {
            if self.isDisposed {
                return disposable
            }

            self.disposables.append(disposable)

            return nil
        }
    }
    private func dispose() {
        let oldDisposables = self._dispose()

        for disposable in oldDisposables {
            // 这里才真正的释放了所有的资源
            disposable.dispose()
        }
    }

    private func _dispose() -> [Disposable] {
        self.lock.performLocked {
              // 首先保存了一个 disposables 的临时变量
            let disposables = self.disposables
            // 随后清空 disposables
            self.disposables.removeAll(keepingCapacity: false)
            // isDisposed 设为 true(用于判断 bag 的资源是否被清空)
            self.isDisposed = true
            // 返回刚才的临时变量,具体的 dispose 是在后面进行的
            return disposables
        }
    }
    
    deinit {
        self.dispose()
    }
}

总结以下几点:

  1. DisposeBag 有一个 disposables 属性, disposables 保存了所有被添加进来的 disposable。
  2. insert 方法把 disposable 添加进 disposables数组中。
  3. dispose 方法的具体执行时机是在 DisposeBag 的实例对象被销毁的时候。
  4. DisposeBag 对象的 dispose 方法做了两件事,第一,清空 disposables 数组。 第二,遍历 disposables 数组,对每一个元素执行他自己的 dispose 方法。

写在最后

这篇文章是我在阅读了部分 RxSwift 代码后的一个总结,如有错误,欢迎指正,大家互相学习。

下一篇: 聊聊 RxSwift 的特征序列