透视RxSwift核心逻辑

透视RxSwift核心逻辑

篇幅稍微有点长,了解程度不同,可以跳过某些部分。

  1. 如果对源码比较熟悉的,建议直接看图就行了,时序图更加清晰。第一次摸索有必要阅读文字内容。
  2. 贴出来的代码省略了不必要的部分,用省略号代替。

示例

RxSwift的基础用法就是很简单的几步

  1. 创建可观察序列
  2. 监听序列(订阅信号)
  3. 销毁序列
//创建序列
let ob = Observable<Any>.create { (observer) -> Disposable in
    //发送信号
    observer.onNext("今日份麻酱凉皮")
    observer.onCompleted()

    return Disposables.create()
}
//订阅信号
let _ = ob.subscribe(onNext: { (text) in
    print("订阅到:\(text)")
}, onError: { (error) in
    print(error)
}, onCompleted: {
    print("完成")
}) {
    print("销毁")
}

控制台输出:

订阅到:今日份麻酱凉皮
完成
销毁

探究

在看源码之前,应该对接触到的类和协议有些认识,方便之后的理解。下面的关系图在需要的时候回头熟悉一下就行:

类关系图.png

到底是什么在支撑如此便捷的调用?

第一句Observable<Any>.create创建了一个可观察序列Observable对象,第二句就是这个Observable序列对象订阅了消息。

从输出可以看出,都是订阅到的消息。那么订阅时传入subscribe的闭包是什么时候调用的呢?

单从现在的几句代码,也能猜出是第一句代码的闭包中的observer.onNext的调用引起的。但是,我们也没有看到这个create函数中的闭包是在哪里执行的?

为了能够清晰的描述,暂且称第一句create中的闭包为create闭包,第二句subscribe中的几个闭包为subscribe闭包

外面看不出来,那我们只能进去RxSwift里面探索下createsubscribe到底做了什么?

create函数的实现

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

原来这函数内部实际上是创建了一个AnonymousObservable匿名可观察序列对象。而之前的闭包也是给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<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)
    }
}

这里在初始化的时候把create闭包赋值给了_subscribeHandler属性。

到此为止,Observable<Any>.create函数实际上创建了一个AnonymousObservable匿名可观察序列对象,并保存了create闭包

一图概千言1.png

。。。貌似这条不是主线啊!没有找到任何一个问题的答案。

再来翻翻subscribe函数

extension ObservableType {
    public func subscribe(onNext: ((E) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)
        -> Disposable {
            let disposable: Disposable
            
            ......
            
            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
            )
    }
}

这也是对定义在ObservableType协议中的函数的实现,返回了一个Disposable。这个Disposable就是用来管理订阅的生命周期的,示例代码中并没有体现出来,实际是在订阅信号的内部处理的。前面都没什么,后面创建了AnonymousObserver,并且在AnonymousObserver初始化时传入了闭包,并赋值给_eventHandler属性。

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

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

之前,AnonymousObservable匿名序列对象,保存了create闭包
此时,创建了AnonymousObserver匿名观察者对象,保存了对subscribe闭包的回调执行的EventHandler闭包

又一条支线。。。一路走来,都是在创建对象,保存闭包。两个主线疑问还是无迹可寻。难道一开始就走上了歧路?非也!继续看下去就明白了什么叫「柳暗花明又一村」。

AnonymousObservablesubscribe函数中,在创建了AnonymousObserver对象后,还返回了一个新建的Disposable对象。重点就在这里的第一个参数:self.asObservable().subscribe(observer)中。asObservable还是返回了self,后面贴上的ObserverType中可以看到。剩下的就是AnonymousObservable的父类Producer中的subscribe了:

class Producer<Element> : Observable<Element> {
    override func subscribe<O : ObserverType>(_ observer: O) -> Disposable where O.E == Element {
        if !CurrentThreadScheduler.isScheduleRequired {
            ......
        } 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
            }
        }
    }
}

由于是在当前线程中执行的,只看else那部分。disposer相关的不用关心。关键是observer参数,这个参数中有对subscribe闭包的处理的EventHandler闭包observer传入了self.run(observer, cancel)。所以,还要回头再看看AnonymousObservable类中的run函数

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

这里又创建了一个AnonymousObservableSink对象,observercancel继续往初始化函数中丢:

final private class AnonymousObservableSink<O: ObserverType>: Sink<O>, ObserverType {
    typealias E = O.E
    typealias Parent = AnonymousObservable<E>
    // state
    private let _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 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.run(self)self传了进来,又对AnonymousObservable起了别名Parentparent._subscribeHandler不就是AnonymousObservable在调用它最开始保存的那个create闭包么?AnyObserver(self)则把AnonymousObservableSink作为AnyObserver初始化的参数。

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

    private let observer: EventHandler

    public init(eventHandler: @escaping EventHandler) {
        self.observer = eventHandler
    }
    
    public init<O : ObserverType>(_ observer: O) where O.E == Element {
        self.observer = observer.on
    }
    public func on(_ event: Event<Element>) {
        return self.observer(event)
    }
    public func asObserver() -> AnyObserver<E> {
        return self
    }
}

其中还把AnonymousObservableSinkon函数赋值给了AnyObserver的属性observerobserver就是EventHandler。这个EventHandlercreate闭包中会用到。

这不就是第二个主线疑问(create函数中的闭包何时调用)的答案么!

整理一下:

  • subscribe(onNext, onError, onCompleted, onDisposed) -> Disposable函数中创建Disposable开始
  • AnonymousObservable调用subscribe(observer)
  • AnonymousObservable调用run(observer, cancel)
  • 创建AnonymousObservableSink(observer: observer, cancel: cancel),并且sink.run(self)
  • parent._subscribeHandler(AnyObserver(self))

这是一条从subscribe闭包-->create闭包的线。

一图概千言2.png

还没完,还有个create闭包中怎么触发subscribe闭包的?

又臭又长的写了这么多,这里就只看observer.onNext("今日份麻酱凉皮")吧。点进去看:
observer.onNext("今日份麻酱凉皮")

extension ObserverType {
    public func onNext(_ element: E) {
        self.on(.next(element))
    }
    
    public func onCompleted() {
        self.on(.completed)
    }
    
    public func onError(_ error: Swift.Error) {
        self.on(.error(error))
    }
}

onNext中调用了on,在前面AnyObserver结构体定义中可以看出,on函数中返回了self.observer(event),之前是把AnonymousObservableSinkon赋值给了这个self.observer,所以,此时会走到AnonymousObservableSinkon函数中。这里面又调用了self.forwardOn(event),看下AnonymousObservableSink的父类Sink中定义的forwardOn

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

    ......

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

    final func forwardOn(_ event: Event<O.E>) {
        ......
        
        self._observer.on(event)
    }
}

forwardOn中走了一句self._observer.on(event)。这里的_observer属性不就是AnonymousObservableSink初始化时传入的AnonymousObserver对象么!

继续跟AnonymousObserveron

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

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

这里没有on,看父类ObserverBase:

class ObserverBase<ElementType> : Disposable, ObserverType {
    typealias E = ElementType
    
    private let _isStopped = AtomicInt(0)

    func on(_ event: Event<E>) {
        switch event {
        case .next:
            if load(self._isStopped) == 0 {
                self.onCore(event)
            }
        case .error, .completed:
            if fetchOr(self._isStopped, 1) == 0 {
                self.onCore(event)
            }
        }
    }
}

这里的on函数中,有个.next分支,调用了self.onCore(event)。子类AnonymousObserver实现的onCore中又调用了self._eventHandler(event)

这个_eventHandler是什么?不就是AnonymousObserver初始化时保存的对subscribe闭包处理的闭包么!所以create闭包中的observer.onNext("今日份麻酱凉皮")就能触发subscribe闭包了。

这是一条从AnonymousObservable调用_subscribeHandler(也就是create闭包)时的参数 AnyObserver-->subscribe闭包的线。

一图概千言3.png

现在我们看清楚了响应式的数据流:

  1. 在订阅信号时创建了observer并执行创建序列时的闭包
  2. 在创建序列的闭包中有回调observer,监听序列的变动而触发订阅信号的闭包

图解

看清楚了么?好像清楚的不太明显。毕竟好几个类、协议,又那么多函数调来调去的。加把劲再撸一撸。既然这么五花八门的调用流程搞清楚了,那就来弄清楚它主要都做了什么?

一图概千言,既然画了图,就少敲点键盘吧!

RxSwift核心逻辑图解四.jpg

仔细看了流程图就会发现,出现的几个类中,干活的主要是Anonymous开头的那三个类。我们在外面调用的操作,其实是在使用RxSwift内部封装的一些类。

  • 创建可观察序列AnonymousObservable,并保存create闭包
  • 订阅信号
    • 首先创建了一个AnonymousObserver,并且把对subscribe闭包的操作封装成了EventHandler
    • 苦力活还是AnonymousObservable来干。
      • 在创建返回值Disposable中,由subscribe(observer),把AnonymousObserver传给了AnonymousObservableSink
        • AnonymousObservableSink才是信息处理的核心,因为他知道的太多了
        • AnonymousObservableSinkAnonymousObserver观察者,AnonymousObserver持有着EventHandler
        • AnonymousObservableSink在调用run函数时也传入了AnonymousObservable序列,AnonymousObservable就是create闭包的持有者。
        • AnonymousObservableSink初始化的时候,除了观察者外,还有个管理序列生命周期的Disposable
      • AnonymousObservableSink作为一个内部类,在被create闭包当做参数回调给外界时需要转换为AnyObserver,在这里AnyObserver则是以闭包属性的形式保留了AnonymousObservableSinkon函数
      • 后面在信号发生改变时就可以让AnyObserver通过这个属性值联系到AnonymousObservableSink

订阅信号:Observable-->AnonymousObservable-->AnonymousObserver-->AnonymousObservableSink-->AnyObserver-->create闭包

  • 发出信号
    • 这个过程基本就是和订阅信号时相反的
    • create闭包中调用AnyObserveronNext开始
    • 通过AnyObserver.observer访问闭包中的AnonymousObservableSink
    • AnonymousObservableSink拥有AnonymousObserver
    • AnonymousObserver掌控EventHandler
    • 句号

发出信号:create闭包-->AnyObserver-->AnonymousObservableSink-->AnonymousObserver-->subscribe闭包

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容

  • 发现 关注 消息 RxSwift入坑解读-你所需要知道的各种概念 沸沸腾关注 2016.11.27 19:11*字...
    枫叶1234阅读 2,780评论 0 2
  • 转载自:https://xiaobailong24.me/2017/03/18/Android-RxJava2.x...
    Young1657阅读 2,016评论 1 9
  • RxSwift 核心原理解析 角色定位 观察者(Observer) 被观察者(Observable) 订阅者(Su...
    狼性刀锋阅读 4,298评论 0 13
  • 转一篇文章 原地址:http://gank.io/post/560e15be2dca930e00da1083 前言...
    jack_hong阅读 905评论 0 2
  • 这段代码中,request.GET['q']是中文,其在网页中显示的效果则是中文的编码。要想显示中文,就得把req...
    提莫总队长阅读 193评论 0 0