RXSwift源码解析2(Sink, SinkDisposer, Producer, AnonymousObservable)

938 阅读9分钟

前言

这部分有点绕,花了半天时间才理清流程。因为相互关联,牵扯的类和子类有五六个,读起来也需要耐心,读时候最好对照源码。以下是我的理解:这部分是Observable 和 Observer 的中间层,主要负责可观察序列的创建,订阅转发和资源的回收。

Create

先来用 create 来创建一个可观察序列并且订阅,最后将返回的 disopose 调用 dispose()

let createClosure : (AnyObserver<Int>) -> Disposable = { (observer) -> Disposable in
    observer.onNext(1)
    return Disposables.create {
        print(observer)
        print("释放了")
    }
}
let createObservable = Observable<Int>.create(createClosure)
let createObserver = AnyObserver<Int> { (event) in
    print(event)
}
let createDispose = createObservable.subscribe(createObserver)
createDispose.dispose()
    

打印如下:

next(1)
释放了

对代码稍作修改,createDispose 不执行 dispose(),让 createClosure 中的 observer 发送 onCompleted 事件

let createClosure : (AnyObserver<Int>) -> Disposable = { (observer) -> Disposable in
    observer.onNext(1)
    observer.onCompleted()
    return Disposables.create {
        print(observer)
        print("释放了")
    }
}
let createObservable = Observable<Int>.create(createClosure)
let createObserver = AnyObserver<Int> { (event) in
    print(event)
}
let _ = createObservable.subscribe(createObserver)
 

看下打印结果:

next(1)
completed
释放了

在后面的源码分析中,会告诉你源码中函数的参数实际是哪个传过去的,所以请记住这几个名字(可以看在上面例子中分别对应的是哪个):

//create函数的参数
createClosure
//create创建的可观察序列
createObservable
//createClosure闭包的参数
closureObserver
//createClosure闭包的返回值
closureDispose
//createObservable 的 observer
createObserver
//createObservable被订阅后的返回的 dispose
createDispose

总结:createDispose 调用 dispose() 方法,closureObserver 发送 onCompleted 都能触发 closureDispose 调用 dispose() 方法。

来思考两个问题:

  1. createObserver 和 closureObserver 是否是一个实例?如果是,怎么关联起来的?如果不是,closureObserver 发送 onNext() 事件,createObserver 为什么能收到事件?
  2. closureDispose 和 createDispose 是否是一个实例?

为了验证这两个问题,来看下内部做了什么操作。先来看下 create 的内部:

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

内部是一个匿名类:AnonymousObservable。那来看下 AnonymousObservable:

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

主要两个方法:

  1. init 方法,参数类型跟 create 方法参数类型相同: AnyObserver<Element>) -> Disposable,将 create 的参数传过来,并保存为属性
  2. 对父类方法的重写 run 方法: override func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element

run 方法是对父类的重写,那再来看下它的父类 Producer

Producer

定义:

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

这里先将线程调度代码先注释掉,这里不研究。主要看他做了什么工作。他还有父类, 那就看下他的父类 Observable (不要害怕,父类做的事情很简单):

public class Observable<Element> : ObservableType {
    // init() {
// #if TRACE_RESOURCES
       // _ = Resources.incrementTotal()
// #endif
   // }
    
    public func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
        rxAbstractMethod()
    }
    
    public func asObservable() -> Observable<Element> {
        return self
    }
    
    // deinit {
// #if TRACE_RESOURCES
       // _ = Resources.decrementTotal()
// #endif
   // }
}

这里一样先把资源统计的代码注释掉,这不是本节关心的。留下主要代码,可以看出该类为抽象类,要求必须子类重写协议方法 subscribe 。回到 Producer看下对该 subscribe 方法是怎么重写的:

    let disposer = SinkDisposer()
    let sinkAndSubscription = self.run(observer, cancel: disposer)
    disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)

    return disposer
  1. 创建 SinkDisposer 实例,该实例主要管理资源的释放工作,后面会具体介绍
  2. 调用 run 方法,返回元组(返回值依赖其他类)
  3. 将 第2步 中的返回值设置为 第1步 创建的实例 disposer 的属性(第2步的返回值是什么也不要着急,因为还有 Sink 和 AnonymousObservableSink 后面要介绍)

这里先来看下第二步的 run 方法,该方法接受两个参数:

  1. observe : 就是 Producer 类重写父类 Observable 的方法 override func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable中的 observer 参数,说白了源头就是 create 创建的 Observable 的 订阅者:createObserver
  2. cancel : 就是上面提到创建的 SinkDisposer 实例,Producer 中创建的 disposer 看一下 run 方法在 Producer 中的实现:
    func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element {
        rxAbstractMethod()
    }

没有实现,要求子类对该方法重写,提供 run 方法,那我们就回到了它的子类 AnonymousObservable。

AnonymousObservable

看下他对 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)
    }
  1. 创建 AnonymousObservableSink 实例,有两个参数,第一个参数 observer,还是上文说的 createObserver。第二个参数 cancel, 就是 Producer 中创建的 SinkDisposer 实例 disposer,它的作用主要是资源的回收。
  2. 调用 第1步 创建的 sink 中 run 方法。(作用是调用了 createClosure 闭包,所以 run 的返回值 subscription 也就是 createClosure 的返回值 Disposables.create{"释放了"} )
  3. 将第 1 步的 sink 和 第2步 的 subscription 返回出去。(返回出去后设置为 Producer 创建的 disposer 的属性,主要做回收处理,后面会说对这两个属性的操作)

我们来看一下 第1步 AnonymousObservableSink 类是干什么的,但是 AnonymousObservableSink 继承自 Sink,先来看下父类 Sink 的作用。(不要怕,东西也不多)

Sink

资源统计debug 等本节无关的先删除了,定义:

class Sink<Observer: ObserverType> : Disposable {
    fileprivate let _observer: Observer
    fileprivate let _cancel: Cancelable
    private let _disposed = AtomicInt(0)


    init(observer: Observer, cancel: Cancelable) {
        self._observer = observer
        self._cancel = cancel
    }

    final func forwardOn(_ event: Event<Observer.Element>) {
        if isFlagSet(self._disposed, 1) {
            return
        }
        self._observer.on(event)
    }

    final var disposed: Bool {
        return isFlagSet(self._disposed, 1)
    }

    func dispose() {
        fetchOr(self._disposed, 1)
        self._cancel.dispose()
    }
}

遵守了 Disposable 协议,把 Disposable 协议也贴一下吧:

public protocol Disposable {
    /// Dispose resource.
    func dispose()
}

初始化需要两个参数,其实就是上面讲到的 AnonymousObservableSink 初始化传进来的两个参数: createObserver 、 Producer 中创建的 SinkDisposer 实例。

还有一个私有属性 private let _disposed = AtomicInt(0) ,记录是否被释放,这里用的 按位与,按位或, 来取值和修改值,这里不详细讲述这个,有兴趣可以具体看下实现 AtomicInt

遵守了 Disposable 协议,所以必须提供 dispose()

    func dispose() {
        fetchOr(self._disposed, 1)
        self._cancel.dispose()
    }

定义的 dispose() 方法,实际也就是调用的 Producer 中创建的 SinkDisposer 实例的 dispose()。fetchOr(self._disposed, 1) 标记这个方法被调用过了。

还剩这个方法:

    final func forwardOn(_ event: Event<Observer.Element>) {
        if isFlagSet(self._disposed, 1) {
            return
        }
        self._observer.on(event)
    }

收到事件,判断当前是否已经 dispose(),如果没有,对事件做转发,让传进来的 createObserver 调用 on(Event) 发出去。

总结: Sink 也很简单,主要是提供两个方法,转发事件 和 释放资源,其实都没有真正的实现,都是调用传进来 两个属性的方法。

AnonymousObservableSink

依然去掉debug 调试的东西,保留主要内容。定义:

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 {
        return parent._subscribeHandler(AnyObserver(self))
    }
}

初始化方法就不再重复了,不知道两个参数的意思的看下上文,就是提供给父类 Sink 的。

还有一个私有属性:private let _isStopped = AtomicInt(0),作用跟 Sink 中的 _disposed 类似,记录当前序列是否终止。

该类还遵守了 ObserverType 协议,所以必须实现协议方法: func on(_ event: Event<Element>):

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

在该方法的实现中,收到 .next() 先判断 _isStopped,如果没有终止,转发事件,否则 return ;收到 .error 或者 .completed, 判断是否终止,没有终止,转发事件,并调用 dispose(),并将 _isStopped 改为终止状态。fetchOr(self._isStopped, 1) 用法见: AtomicInt

有没有注意到这里接收到事件是调用的 self.forwardOn(event) ,上文说过 self.forwardOn(event) 实现是调用的 createObserver 的 on(Event) 方法。

最后来看下 run 方法:

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

是否还记得 AnonymousObservable 中的关键代码:

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

let subscription = sink.run(self) ,之前说过这段代码是对 createClosure 闭包的调用,_subscribeHandler 保存的就是 createClosure ,现在来看 run 方法的实现:

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

parent._subscribeHandler(AnyObserver(self)) ,参数 AnyObserver(self),这里的 self 是 AnonymousObservableSink 实例(AnyObserver(self) 是用 AnonymousObservableSink 实例构造了一个 AnyObserver 实例)。AnyObserver(self) 是 _subscribeHandler 的参数,_subscribeHandler 保存的是 createClosure,也就是说 closureObserver 是这个 AnyObserver(self)。

所以 closureObserver.onNext(1) 调用的是这里 AnyObserver(self) 实例中的 onNext(Event) 方法, AnyObserver(self) 是用 AnonymousObservableSink 生成的,实际还是调用的 AnonymousObservableSink 类中的 on(_ event: Event<Element>) 方法,而该类中 on(Event) 方法内部的本质是转发,最终调用的是 createObserver.onNext(1)。这就说明了为什么 closureObserver 调用 onNext(1), createObserver 能够响应。也说明 closureObserver 和 createObserver 并不是一个实例,closureObserver 发送事件 createObserver 可以收到,只是内部转发给了 createObserver。

再来看最后一行代码: return (sink: sink, subscription: subscription) 最后返回 sink 和 subscription。

回到 Producer 的代码:

        let disposer = SinkDisposer()
        let sinkAndSubscription = self.run(observer, cancel: disposer)
        disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)

        return disposer

返回值设置为 disposer 实例的两个属性。第一个属性:做转发的 sink( Sink 类实现了 Disposable 协议), 第二个属性实际就是: closureDispose

return disposer

也就是说 createDispose 是这里的 disposer 也就是 SinkDisposer 实例。

SinkDisposer

定义:

private final class SinkDisposer: Cancelable {
    private enum DisposeState: Int32 {
        case disposed = 1
        case sinkAndSubscriptionSet = 2
    }

    private let _state = AtomicInt(0)
    private var _sink: Disposable?
    private var _subscription: Disposable?

    var isDisposed: Bool {
        return isFlagSet(self._state, DisposeState.disposed.rawValue)
    }

    func setSinkAndSubscription(sink: Disposable, subscription: Disposable) {
        self._sink = sink
        self._subscription = subscription

        let previousState = fetchOr(self._state, DisposeState.sinkAndSubscriptionSet.rawValue)
        if (previousState & DisposeState.sinkAndSubscriptionSet.rawValue) != 0 {
            rxFatalError("Sink and subscription were already set")
        }

        if (previousState & DisposeState.disposed.rawValue) != 0 {
            sink.dispose()
            subscription.dispose()
            self._sink = nil
            self._subscription = nil
        }
    }

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

提供两个方法,简单描述一下主要作用:

  1. func setSinkAndSubscription(sink: Disposable, subscription: Disposable) :设置 sink 和 subscription,将两个参数存储为属性。如果当前状态 是 disposed ,将参数 dispose(),并且将属性置 nil

  2. func dispose() :_sink 和 _subscription 调用 dispose(), 并且设置为 nil

createDispose 调用 dispose() 也就是调用了这里的 dispose() 方法。释放转发用的 sink 和 closureDispose, 并调用 sink 和 closureDispose 的 dispose()。

所以 createDispose 调用 dispose() ,这里内部做了closureDispose 调用dispose()。这就是为什么 createDispose 调用 dispose() ,可以打印 释放了 。

closureObserver 调用 onCompleted() 为什么也能打印 释放了?还记得 AnonymousObservableSink 中 on() 方法做转发时候,收到 .error, .completed事件还额外做了什么操作吗?

        case .error, .completed:
            if fetchOr(self._isStopped, 1) == 0 {
                self.forwardOn(event)
                self.dispose()
            }
        }

前面说过,这里的 dispose() 也没有真正实现,是调用的传进来的 _cancel 的 dispose(),这个 _cancel 就是 Producer 中创建的 disposer。所以 closureObserver 调用 onCompleted(),使 disposer 调用了 dispose()。 dispose() 中对_subscription 做了释放操作。

开头的第2个问题: createDispose 是 Producer 中创建的 disposer, closureDispose 是 disposer 中的属性 _subscription。所以,开头提到的第二个问题,createDispose 和 closureDispose 也不是同一个实例

有没有发现 AnonymousObservableSink 和 SinkDisposer 这两个类在相互引用?所以这里会造成循环引用,打破循环引用的方法,也就是在合适的时机 调用 这两个类中任意的一个 dispose() 方法。如果没有手动调用 dispose(),需要加入 DisposeBag 中,做到统一释放

留言

确实有点绕,有讲的不清楚的地方,欢迎留言。