RxSwift核心邏輯簡介

爲何要使用RxSwift

一、Swift是一種靜態語言。靜態語言對於數值的傳遞、響應的回調、通信等有必定的影響。不像OC有運行時,能夠動態的發送消息。因此須要RXSwift來彌補靜態語言上的不足。html

二、RxSwift的思想是函數響應式編程,很符合Swift函數是一等公民的設計思想,也是之後Swift發展的方向。react

三、RxSwift是ReactiveX家族的一員。瞭解RxSwift後,能夠拓展到ReactiveX家族的其餘框架。編程

函數響應式編程

一、函數式swift

​ 函數來源於數學,用 y = f(x)表示,其中,y是因變量,x是自變量。y會隨着x的變化而變化。設計模式

​ 在swift中,x至關於一個參數,f是函數,y就是函數的結果—返回值。閉包

​ 在必定狀況下,x能夠表示爲 x = f(x),則,上面的公式能夠變形爲 y = f(f(x))。即一個函數的參數能夠是另外一個函數。增長了函數的靈活性。 這就是函數式編程的核心思想。框架

二、函數響應式函數式編程

​ 舉例說明:函數

var a: Int = 10        
var b: Int = a + 10 
複製代碼

若是上面的代碼中 b 的值須要一直跟隨a的值發生變化,咱們須要怎麼來實現呢?咱們須要監聽a的值變化,而b響應a的變化而變化。這就是OC中的KVO機制。源碼分析

可是,很遺憾,Swift中沒有KVO鍵值監聽。因此,咱們須要RxSwift來實現更高級更方便的函數響應式編程。

體驗RxSwift的使用魅力

  • KVO監聽person中的name屬性
self.person.rx.observeWeakly(String.self, "name")
    .subscribe(onNext:{(value) in
        print(value as Any)
    })
    .disposed(by: disposeBag)
複製代碼
  • 監聽按鈕的點擊事件
self.button.rx.tap
    .subscribe(onNext: {(value) in 
        print("點擊了按鈕")
    })
    .disposed(by: disposeBag)
複製代碼
  • 監聽輸入框的輸入
self.textFiled.rx.text.orEmpty
    .subscribe(onNext: {(text) in
	print(text)
    })
    .disposed(by: disposeBag)
複製代碼
  • UITextFiled輸入綁定UILabel
self.textFiled.rx.text
		.bind(to: self.button.rx.title())
		.disposed(by: disposeBag)
複製代碼
  • 手勢監聽
let tap = UITapGestureRecognizer()
self.label.addGestureRecognizer(tap)
self.label.isUserInteractionEnable = true
tap.rx.event.subscribe(onNext: {(tap) in
		print(tap.view)
})
.disposed(by: disposeBag)
複製代碼
  • 監聽通知
NotificationCenter.default.rx.notifcation(UIResponder.keyboardWillShowNotification)
.subscribe(onNext: {(noti) in
		print(noti)
})
.disposed(by: disposeBag)
複製代碼
  • 定時器
timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance)

timer.subscribe(onNext: {(num) in
    print(num)
})
.disposed(by: disposeBag)
複製代碼

RxSwift核心原理分析

RxSwift使用三步曲

第一步:建立序列

let ob = Observable<String>.create { (observer) -> Disposable in
            
    return Disposables.create()
}
複製代碼

第二步:訂閱信號

let _ = ob.subscribe(onNext: { (text) in
    print("訂閱信息: \(text)")
}, onError: { (error) in
    print("error: \(error)")
}, onCompleted: {
    print("訂閱結束")
}) {
    print("已銷燬")
}
複製代碼

第三步:發送信號

let ob = Observable<String>.create { (observer) -> Disposable in
            
    // 第三步:發送信號
    observer.onNext("信息1")
            
    return Disposables.create()
}
複製代碼

RxSwift源碼分析

  • 首先分析第一步建立序列。使用Observable的create方法建立可觀察序列。

查看RxSwift源碼

發現好像沒有內部實現,只有一個函數聲明,那咱們去哪裏查看實現呢?喬布斯曾經說過,看源碼不只要看代碼,還要看文檔註釋!!!

因此咱們往上看註釋,會發現有一個「seealso」,翻譯過來是「另見」。咦,彷佛是須要查看其餘文檔的意思。而且後面跟了一個連接,那咱們是要去看文檔嗎?

咱們先來分析一下這個連接,reactivex.io/documentati…,最後指向了一個create文件的html,那咱們猜想是不是源碼中有一個Create文件呢,咱們如今項目中來搜索一下

搜索後發現確實有一個Create文件,點進去看一下

能找到一個ObservableType的擴展,實現了一個create方法。

其返回值爲AnonymousObservable(subscribe)。一個內部匿名可觀察序列類。參數subscribe則爲第一步建立序列中的閉包。

同時,在這個文件的下方能找到AnonymousObservable匿名內部可觀察序列類的實現

實現很簡單,init初始化時保存了傳入的閉包,至此,第一步建立序列完成。

  • 第二步:訂閱信號 使用ObservableType的subscribe訂閱信號。

找到源碼

分析發現,藍色框之外的代碼做用是回收,真正訂閱的關鍵代碼是藍色方框之內的代碼。那咱們主要看一下這一部分。
首先建立了一個匿名的觀察者AnonymousObserver,其實現和匿名可觀察序列相似,都是保存建立時的閉包。函數結束時return一個Disposables對象。

分析到這裏你們是否是以爲很奇怪?第一步的可觀察序列有了,第二步的觀察者也有了,可是他們之間彷佛沒有聯繫啊,怎麼訂閱的?以及第三步的發送信號又是如何執行的呢?

咱們找來找去,彷佛只可能在

這句代碼中,好,咱們一塊兒去驗證一下咱們的猜測。

self.asObservable().subscribe(observer)
複製代碼

咱們先看看asObservable(),點擊查看一下,咦,點不進去。咱們再點查看一下subscribe(observer),咦,好像也找不到實現。好吧,咱們再往前看是self,self咱們知道是第一步建立的可觀察序列

在這個類裏面,咱們找到了 asObservable()subscribe 函數, asObservable()的做用僅僅是返回自身self。

咱們再看看subscribe方法。 內部調用了rxAbstractMethod()方法。可是通過查看,這個方法並無被實現。分析到這裏又分析不下去了。咱們再回想一下,Observable對象是由create方法建立的。而且其內部是初始化了一個內部匿名可觀察序列的實例對象。咱們再回到Create文件查看一下源碼。發現其也沒有subscribe 函數。

可是能夠發現,AnonymousObservable類是繼承至Producer類,那subscribe函數會不會是其父類Producer的方法呢?

經過查看源碼

Producer對象有 subscribe函數而且經過斷點運行會發現,會走到else中的方法。調用了 self.run(observer, cancel: disposer)

在下方找到run函數。發現其內部只有一個rxAbstractMethod()函數調用。真正的run函數並無實現。其實,這是一種設計模式。有好奇心的寶寶能夠自行了解一下。這裏就不展開敘述了。這個run函數其實剛纔咱們已將看到過了,Producer對象的子類AnonymousObservable匿名可觀察序列類裏

重點來了,敲黑板!!!

在這個方法中,傳入了以前建立的匿名觀察者AnonymousObserver實例對象。而且建立了一個AnonymousObservableSink實例對象,並調用了它的run()函數。咱們看一下這個run()函數的實現。實際上是調用了parent._subscribeHandler(AnyObserver(self))parent就是AnonymousObservable的實例。也就是調用了AnonymousObservable._subscribeHandler(AnyObserver(self))

咱們在分析第一步建立可觀察序列的時候已經知道,這裏的_subscribeHandler保存的其實就是第一步建立可觀察序列傳入的閉包。如今調用_subscribeHandler便是執行了這個閉包。而閉包中的方法就是第三步發送信號

通過上面的源碼分析,已經知道了從建立可觀察序列-->訂閱信號-->發送信號這一系列的數據流轉過程。

  • 第三步 發送信號 調用observer.onNext()函數發送信號。

以前已經分析過了,在第二步訂閱信號的時候,建立了一個內部匿名觀察者observer。這個observer又是如何傳遞給第一步建立序列的閉包中的呢?下面咱們就來分析一下。

咱們知道,在第二步訂閱信號調用subscribe的return中,調用了Producer對象的subscribe函數,並將observer做爲參數傳遞過去。而在subscribe函數中調用子類AnonymousObservable匿名可觀察序列類的run函數時,將observer做爲參數傳遞到了run函數中。

AnonymousObservable.run函數中,初始化AnonymousObservableSink實例時,又將observer傳遞給了AnonymousObservableSink實例對象。並在調用run函數時,經過AnonymousObservableSink實例對象建立AnyObserver實例,從而傳遞到了建立序列的閉包中,獲得一個觀察者observer

經過調用觀察者observer對象的onNext()函數,便可調用到第二步訂閱信號閉包中的onNext回調。從而發送已經傳遞訂閱信息。

通過上面的分析過程,RxSwift的源碼已經分析完畢。RxSwift的核心原理也瞭解得比較清晰。可是,RxSwift中所用到的設計模式已經編程思想倒是須要咱們在之後的使用中不斷學習已經掌握的。

最後,附上RxSwift的一個源碼分析思惟導圖,但願對你們有所幫助。

相關文章
相關標籤/搜索