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

868 阅读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. createObserverclosureObserver 是否是一个实例?如果是,怎么关联起来的?如果不是,closureObserver 发送 onNext() 事件,createObserver 为什么能收到事件?
  2. closureDisposecreateDispose 是否是一个实例?

为了验证这两个问题,来看下内部做了什么操作。先来看下 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步的返回值是什么也不要着急,因为还有 SinkAnonymousObservableSink 后面要介绍)

这里先来看下第二步的 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步 创建的 sinkrun 方法。(作用是调用了 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 初始化传进来的两个参数: createObserverProducer 中创建的 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) 实现是调用的 createObserveron(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),这里的 selfAnonymousObservableSink 实例(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 能够响应。也说明 closureObservercreateObserver 并不是一个实例,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 实例的两个属性。第一个属性:做转发的 sinkSink 类实现了 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)设置 sinksubscription,将两个参数存储为属性。如果当前状态 是 disposed ,将参数 dispose(),并且将属性置 nil

  2. func dispose()_sink_subscription 调用 dispose(), 并且设置为 nil

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

所以 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() 也没有真正实现,是调用的传进来的 _canceldispose(),这个 _cancel 就是 Producer 中创建的 disposer。所以 closureObserver 调用 onCompleted(),使 disposer 调用了 dispose()dispose() 中对_subscription 做了释放操作。

开头的第2个问题: createDisposeProducer 中创建的 disposerclosureDisposedisposer 中的属性 _subscription。所以,开头提到的第二个问题,createDisposeclosureDispose 也不是同一个实例

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

留言

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