RXSwift-核心邏輯

基本概念


要想充分理解RXSwift核心邏輯逛绵,那么首先必須要知道RXSwift里包含哪幾個角色,以及它們的職責(zé)。

被觀察者(Observable)

它主要負(fù)責(zé)產(chǎn)生事件揽乱,實(shí)質(zhì)上就是一個可被監(jiān)聽的序列(Sequence)雷逆。

Observable<T>這個類就是Rx框架的基礎(chǔ)弦讽,我們稱它為可觀察序列

Observable<T> ==異步產(chǎn)生==> event(element : T)

被觀察者(Observable)類繼承關(guān)系

觀察者(Observer)

它主要負(fù)責(zé)監(jiān)聽事件然后對這個事件做出響應(yīng),或者說任何響應(yīng)事件的行為都是觀察者往产。

觀察者(Observer)類繼承關(guān)系

訂閱者(Subscriber)

事件的最終處理者

管道(Sink)

Observer 和 Observable 溝通的橋梁:Sink相當(dāng)與一個加工者被碗,可以將源事件流轉(zhuǎn)換成一個新的事件流,如果將事件流比作水流仿村,事件的傳遞過程比作水管锐朴,那么Sink就相當(dāng)于水管中的一個轉(zhuǎn)換頭。

管道(Sink)類繼承關(guān)系

代碼解析


接下來我們結(jié)合以下很簡單的代碼來分析蔼囊,逐步揭開RXSwift的神秘面紗焚志。

//1:創(chuàng)建序列
 let ob = Observable<Any>.create { (observer) -> Disposable in
            // 3:發(fā)送信號
            obserber.onNext("測試OnNext")
            obserber.onCompleted()
            obserber.onError(NSError.init(domain: "error!", code: 000, userInfo: nil))
            return Disposables.create()
 
//2:訂閱信息
 let _ = ob.subscribe(onNext: { (text) in
            print("訂閱到:\(text)")    //text從哪里來的畏鼓?
        }, onError: { (error) in
            print("error: \(error)")    //error從哪里來的酱酬?
        }, onCompleted: {
            print("完成")
        }) {
            print("銷毀")
        }

在這里我們主要關(guān)注下
create 閉包什么時候執(zhí)行,
subscribe 閉包又是什么時候執(zhí)行的
也就是3->2這條線

Create方法

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

我們看到create 函數(shù)云矫, 返回了一個AnonymousObservable實(shí)例膳沽,接著我們進(jìn)入AnonymousObservable看它里面具體內(nèi)容

// AnonymousObservable  Class
final fileprivate 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)
    }
}

在這里我們再次回顧下Observable集成體系
(父類)
ObservableConvertibleType(完全的抽象)
|
ObservableType( 處理subscribe)
|
Observable(處理 asObservable)
|
Producer(重載subscribe)
|
AnonymousObservable(處理run)
(子類)

PS:由上面我們能看出,如果想自定義Observable通常只需要繼承Producer让禀, 并實(shí)現(xiàn)run方法就可以了挑社。

在這里我們看到Run方法里面涉及了類AnonymousObservableSink,它作為Observer 和 Observable的銜接的橋梁我們看到它本身遵守ObseverType協(xié)議,與此同時實(shí)現(xiàn)了run方法巡揍。

那也就是說痛阻,sink從某種程度來說也是Observable
通過sink就可以完成從Observable到Obsever的轉(zhuǎn)變。

總結(jié)下create方法主要工作:

  • 創(chuàng)建AnonymousObservable對象腮敌,
  • _subscribeHandler保存了閉包
  • 寫了run方法在內(nèi)部創(chuàng)建了AnonymousObservableSink

Subscribe方法

 public func subscribe(_ on: @escaping (Event<E>) -> Void)
        -> Disposable {
            let observer = AnonymousObserver { e in
                on(e)
            }
            return self.asObservable().subscribe(observer)
    }

上述代碼只是入口阱当,下面的才是核心(Producer里面)

// Producer Class
  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
            }
        }
    }

這里面我們看到了Producer調(diào)用了自己的run方法,而AnonymousObservableSink作為其子類重寫了該方法缀皱,我們先去看下子類是如何寫的斗这。

// AnonymousObservable Class
    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注意Sink是持有Observer啤斗,從這也可以看出來

Observerablerun方法觸發(fā)Sinkrun方法

接下來就要關(guān)注AnonymousObservableSink方法表箭。

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

在這里我們再一次見到了subscribeHandler,這個subscribeHandler就是之前最開始的閉包钮莲!

 Observable<String>.create { observer -> Disposable in
            observer.onNext("測試")
            return Disposables.create()
        }

至此我們知道了create閉包是什么執(zhí)行的了免钻,接下來我們自然的把目光鎖定到實(shí)體類AnyObserver,看看它里面究竟是如何實(shí)現(xiàn)的崔拥。

public struct AnyObserver<Element> : ObserverType {
    /// The type of elements in sequence that observer can observe.
    public typealias E = Element
    
    /// Anonymous event handler type.
    public typealias EventHandler = (Event<Element>) -> Void

    private let observer: EventHandler

    /// Construct an instance whose `on(event)` calls `eventHandler(event)`
    ///
    /// - parameter eventHandler: Event handler that observes sequences events.
    public init(eventHandler: @escaping EventHandler) {
        self.observer = eventHandler
    }
    
    /// Construct an instance whose `on(event)` calls `observer.on(event)`
    ///
    /// - parameter observer: Observer that receives sequence events.
    public init<O : ObserverType>(_ observer: O) where O.E == Element {
        self.observer = observer.on
    }
    
    /// Send `event` to this observer.
    ///
    /// - parameter event: Event instance.
    public func on(_ event: Event<Element>) {
        return self.observer(event)
    }

    /// Erases type of observer and returns canonical observer.
    ///
    /// - returns: type erased observer.
    public func asObserver() -> AnyObserver<E> {
        return self
    }
}

在這里我們看到其內(nèi)部的Observer其實(shí)是一個EventHandler极舔,并且在初始化的時候把外部傳過來的AnonymousObservableSink.on賦值給了這個Observer,也就是說observer.onNext("測試")最終會觸發(fā)AnonymousObservableSink.on事件

接著我們看下AnonymousObservableSinkon的具體實(shí)現(xiàn)

// AnonymousObservableSink.on

    func on(_ event: Event<E>) {
        #if DEBUG
            _synchronizationTracker.register(synchronizationErrorMessage: .default)
            defer { _synchronizationTracker.unregister() }
        #endif
        switch event {
        case .next:
            if _isStopped == 1 {
                return
            }
            forwardOn(event)
        case .error, .completed:
            if AtomicCompareAndSwap(0, 1, &_isStopped) {
                forwardOn(event)
                dispose()
            }
        }
    }

AnonymousObservableSinkon會調(diào)用其內(nèi)部的forwardOn

// Sink.forwardOn
    final func forwardOn(_ event: Event<O.E>) {
        #if DEBUG
            _synchronizationTracker.register(synchronizationErrorMessage: .default)
            defer { _synchronizationTracker.unregister() }
        #endif
        if _disposed {
            return
        }
        _observer.on(event)
    }

在這里還記得這個_observer的實(shí)體嗎链瓦,看到下面代碼你一定會回憶起來拆魏,

  public func subscribe(_ on: @escaping (Event<E>) -> Void)
        -> Disposable {
            let observer = AnonymousObserver { e in
                on(e)
            return self.asObservable().subscribe(observer)
    }

對盯桦,沒錯,這個_observer就是我們最初傳進(jìn)來的subscribe閉包的實(shí)體類AnonymousObserver~!

接著我們繼續(xù)看下這個AnonymousObserveron方法又是如何實(shí)現(xiàn)的

繼承關(guān)系:AnonymousObserver->ObserverBase->ObserverType

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

ObserverBase.on會觸發(fā)onCore方法渤刃,看下子類的實(shí)現(xiàn)

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

這里的_eventHandler還記得嗎拥峦?它就是最初傳進(jìn)來的訂閱閉包即:

            .subscribe { event in
               print(event.element)
        }

總結(jié)一下


Observable-Create階段:

  • 創(chuàng)建AnonymousObservable
  • 保存閉包(subscribeHandler)

Observable-Subscribe階段:

  • 創(chuàng)建AnonymousObserver
  • 調(diào)用自己(AnonymousObservable)的run方法:(AnonymousObserver作為參數(shù))
    AnonymousObservable重寫了run,它在方法里面創(chuàng)建了AnonymousObservableSink并在sink里保存了這個剛創(chuàng)建的AnonymousObserver
  • 調(diào)用AnonymousObservableSinkrunrun方法里用到AnonymousObservable_subscribeHandler并傳入AnyObserver卖子,這里AnonymousObservableSink.on賦值給了AnyObserver內(nèi)部的EventHandler成員observer

執(zhí)行階段:

AnyObserver.on ----> AnonymousObservableSink.on ----> AnonymousObservableSink.forwardOn ----> AnonymousObserver.on---> AnonymousObserver.onCore ----> _eventHandler(event)

PS:

可以看出Sink在不同的階段有著不同的身份

  • Sink充當(dāng)Observable
    Obsevable.subscribe ---> Obsevable.run ----> Sink.run
    這個過程通過Sink建立Obsevable和 Observer的聯(lián)系
  • Sink充當(dāng)Observer
    AnyObserver.on ----> Sink.on ----> Observer.on ---> Observer.OnCore
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末略号,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子洋闽,更是在濱河造成了極大的恐慌玄柠,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诫舅,死亡現(xiàn)場離奇詭異羽利,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)骚勘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進(jìn)店門铐伴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人俏讹,你說我怎么就攤上這事⌒蟮酰” “怎么了泽疆?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長玲献。 經(jīng)常有香客問我殉疼,道長,這世上最難降的妖魔是什么捌年? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任瓢娜,我火速辦了婚禮,結(jié)果婚禮上礼预,老公的妹妹穿的比我還像新娘眠砾。我一直安慰自己,他們只是感情好托酸,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布褒颈。 她就那樣靜靜地躺著,像睡著了一般励堡。 火紅的嫁衣襯著肌膚如雪谷丸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天应结,我揣著相機(jī)與錄音刨疼,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛揩慕,可吹牛的內(nèi)容都是我干的亭畜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼漩绵,長吁一口氣:“原來是場噩夢啊……” “哼贱案!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起止吐,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤宝踪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后碍扔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瘩燥,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年不同,在試婚紗的時候發(fā)現(xiàn)自己被綠了厉膀。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡二拐,死狀恐怖服鹅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情百新,我是刑警寧澤企软,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站饭望,受9級特大地震影響仗哨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜铅辞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一厌漂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧斟珊,春花似錦苇倡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至高职,卻和暖如春钩乍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背怔锌。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工寥粹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留变过,地道東北人。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓涝涤,卻偏偏與公主長得像媚狰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子阔拳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評論 2 355