RxSwift學(xué)習(xí)教程之基礎(chǔ)篇
前言
我們在 iOS 開發(fā)過程中,幾乎無時無刻都要面對異步事件的處理。例如,按鍵點擊、數(shù)據(jù)保存、、音頻后臺播放、交互動畫展示。這些事件并不具備特定時序性,甚至它們可能同時發(fā)生。
雖然 Apple 提供了通知、代理、GCD、閉包等異步機制,但是這些機制缺乏一個統(tǒng)一的抽象表述。另外,這些機制在處理共享的可變數(shù)據(jù)或狀態(tài)時不夠清晰簡練。當(dāng)然,這并不是說編寫優(yōu)雅的異步代碼不現(xiàn)實。畢竟與其他平臺相比 iOS 的異步機制還是很強大的。
幸運的是,我們能夠通過 RxSwift 優(yōu)雅的處理異步代碼。
至于 RxSwift 的優(yōu)勢以及為什么要使用它,詳見文檔。這里就不廢話了。
RxSwift 簡介
其實響應(yīng)式編程并不是一個什么新的概念,只不過是最近幾年受到了開發(fā)者更多的關(guān)注。它最早由巨硬提出,主要的目的是為了應(yīng)對復(fù)雜的 UI 異步事件和應(yīng)用實時響應(yīng)。社區(qū)中也已經(jīng)有了各種語言版本的響應(yīng)式編程實現(xiàn),包括:RxJS、RxKotlin、Rx.NET、RxScala、RxSwift。這些類庫僅僅只是實現(xiàn)方式存在差異,所以開發(fā)者在討論應(yīng)用邏輯時不會存在溝通障礙。
RxSwift 作為 Swift 語言的響應(yīng)式編程實現(xiàn),它在傳統(tǒng)的命令式編程和純函數(shù)式編程中找到了一個很好的平衡點。通過使用不可變代碼定義異步處理輸入,RxSwift 以一種確定可組合的形式對事件做出響應(yīng)。
總的來說,RxSwift 有三個主要構(gòu)成部分:Observable、Operator、Scheduler 。下面我們就來一一介紹。
Observable
Observable<T>
類可以說是 RxSwift 整個框架的基石。它能異步的觸發(fā)一系列事件流并攜帶不可更改的狀態(tài)變量。簡單來說就是:它能讓某個類的實例在一段時間內(nèi)實現(xiàn)對另一個實例對象值的觀察。例如:觀察者可以捕獲對所有可觀察對象觸發(fā)的事件,從而實現(xiàn) UI 的實時更新或者是數(shù)據(jù)的實時處理。
其中 Observable<T>
類遵循了 ObservableType 協(xié)議。另外,Observable 對象所能觸發(fā)的事件只有以下三種:
- next 事件:該事件在觸發(fā)時會將可觀察對象的最新值傳遞給觀察者。
- completed 事件:該事件意味著可觀察對象的生命周期正常結(jié)束不會在繼續(xù)觸發(fā)事件。
- error 事件:該事件表明可觀察對象出現(xiàn)了錯誤導(dǎo)致生命周期異常終止。
對于一個可觀察的整型變量來說,異步環(huán)境下它所觸發(fā)的事件可以在時間線上被描繪成這樣一個事件序列:
另外,我們可以對這三類事件進行組合從而實現(xiàn)更為復(fù)雜的業(yè)務(wù)邏輯。與此同時,我們還可以使用該機制輕松實現(xiàn)代碼解耦和多個對象間數(shù)據(jù)傳遞,無需編寫代理或者閉包代碼。
這里,我們還有一點值得注意。那就是可觀察序列其實有兩種類型。
有限觀察序列( Finite observable sequences )
該序列是指那些最后會以 completed 或者 error 事件終極生命周期的可觀察對象。最典型的例子就是,通過 API 進行網(wǎng)絡(luò)請求:
- 開始數(shù)據(jù)請求并準(zhǔn)備進行數(shù)據(jù)接收。
- 接收到服務(wù)端響應(yīng)開始接收數(shù)據(jù)。
- 如果服務(wù)器或者網(wǎng)絡(luò)發(fā)生故障則關(guān)閉請求并觸發(fā)錯誤處理。
- 如果一切正常則對請求數(shù)據(jù)進行處理和分析。
下面是一個文件下載請求的 Rx 范式的代碼:
API.download(file: "http://www...") .subscribe( onNext: { data in append data to temporary file }, onError: { error in display error to user }, onCompleted: { use downloaded file })
這段代碼中 API.download (file:)
函數(shù)會創(chuàng)建一個 Observable<Data>
實例對象,并且在整個數(shù)據(jù)接收過程中會不斷的觸發(fā) next 事件。然后,我們在 next 事件中會將這些片段數(shù)據(jù)保存到臨時文件中。如果此過程出現(xiàn)錯誤的話,我們會將錯誤信息展示給用戶。如果一切順利我們會將臨時文件保存到設(shè)備中。最后在下載完成后,我們可以在 completed 進行下一步的邏輯處理。
無限觀察序列( Infinite observable sequences )
與網(wǎng)絡(luò)任務(wù)不同的是,UI 以及交互事件是無限觀察序列。它們并不存在一個明確的生命周期終結(jié)點。例如,針對可能的設(shè)備方向旋轉(zhuǎn),我們需要實時進行布局修改。而設(shè)備的方向旋轉(zhuǎn)本身是隨機發(fā)生的并且與應(yīng)用本身具有同樣的生命周期。因此 Rx 也需要一種機制支持這種無限觀察序列。
針對這種情況,在 RxSwift 中我們可以通過以下代碼來應(yīng)對:
UIDevice.rx.orientation.subscribe(onNext: { current in switch current { case .landscape: re-arrange UI for landscape case .portrait: re-arrange UI for portrait } })
操作符
ObservableType 以及 Observable 類的實現(xiàn)中都包含大量的異步處理方法,這些方法也被稱為操作符。由于這些操作符只是進行異步輸入處理并產(chǎn)生對應(yīng)輸出,所以它并不會對應(yīng)用產(chǎn)生多余的副作用。另外,因為操作符之間的高度解耦所以我們很容易對它進行組合以期實現(xiàn)復(fù)雜的功能。
例如,對于上面的設(shè)備方向旋轉(zhuǎn),我們可以對所有的情況進行過濾然后對部分值進行進一步處理。
UIDevice.rx.orientation .filter { value in return value != .landscape } .map { _ in return "Portrait is the best!" } .subscribe( onNext: { string in showAlert(text: string) })
上面的代碼中,我們首先會將所有 .landscape 方向過濾掉不做任何處理。然后,我們再將剩下的 portrait 轉(zhuǎn)化為字符串 Portrait is the best! 。整個處理流程大致如下:
這種函數(shù)式的操作符讓我們可以靈活的組合出更強大的功能。
Scheduler
Schedulers 是一個與 GCD 相對應(yīng)的概念,只不過前者使用起來更為方便。RxSwift 中預(yù)定義的 Schedulers 足夠開發(fā)者應(yīng)對絕大多數(shù)的編程場景。
例如,我們可以使用串型序列 SerialDispatchQueueScheduler 來處理 next 事件,通過 ConcurrentDispatchQueueScheduler 運行并行文件下載任務(wù),通過 OperationQueueScheduler 運行一個 NSOperationQueue 操作隊列。甚至你可以在同一個觀察對象的不同任務(wù)中使用不同的 Schedulers 類型,如下圖:
我們將左側(cè)的任務(wù)用不同的顏色加以區(qū)分,然后在右側(cè)任務(wù)被拆分為不同的步驟并且放在不同 Schedulers 中。例如,network subscription 任務(wù)就被拆分為三個步驟并依次放入了 Custom NSOperation Scheduler 、Background Concurrent Scheduler、Main Thred Serial Scheduler 。
補充
值得注意的是, RxSwift 并沒有對客戶端的應(yīng)用架構(gòu)作出硬性規(guī)定。這意味著,我們可以在已有項目中引入 RxSwift 進行響應(yīng)式編程實踐。當(dāng)然已有框架中必定存在一個最適合 RxSwift 的,而它就是 MVVM。因為在 MVVM 中我們可以將 VM 中的部分屬性直接與 UI 進行綁定。
另外,對于 iOS 編程來說僅僅有 RxSwift 是遠(yuǎn)遠(yuǎn)不夠的。RxSwift 只是 Swift 語言的響應(yīng)式實現(xiàn),我們還需要一種 Cocoa 層面的實現(xiàn)。好在這里存在 RxCocoa 作為 UIKit 的響應(yīng)式補充。前面設(shè)備方向代碼 UIDevice.rx.orientation
就是 RxCocoa 的應(yīng)用 。
總結(jié)
作為系列開篇,本文介紹了 RxSwift 的一些基本理念和構(gòu)成,更多相關(guān)的內(nèi)容將會在后面帶來。
好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
RxSwift學(xué)習(xí)之Observable的新建、訂閱及取消訂閱
這篇文章主要給大家介紹了關(guān)于RxSwift學(xué)習(xí)教程之Observable的相關(guān)資料,文中詳細(xì)的給大家介紹了關(guān)于新建Observable、訂閱Observable和取消訂閱并消除內(nèi)存泄漏等相關(guān)的內(nèi)容,需要的朋友可以參考借鑒,下面來一起看看吧。2017-09-09Swift實現(xiàn)監(jiān)聽鍵盤通知及一些處理詳解
這篇文章主要給大家介紹了關(guān)于Swift實現(xiàn)監(jiān)聽鍵盤通知及一些處理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-01-01iPhone與iWatch連接、控制、數(shù)據(jù)傳遞(Swift)的方法
這篇文章主要介紹了iPhone與iWatch連接、控制、數(shù)據(jù)傳遞(Swift)的方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-03-03Swift 使用 Observe 監(jiān)測頁面滾動的實現(xiàn)方法
這篇文章主要介紹了Swift 使用 Observe 監(jiān)測頁面滾動的實現(xiàn)方法,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05淺談在Swift中關(guān)于函數(shù)指針的實現(xiàn)
這篇文章主要介紹了淺談在Swift中關(guān)于函數(shù)指針的實現(xiàn),是作者根據(jù)C語言的指針特性在Swifft中做出的一個實驗,需要的朋友可以參考下2015-07-07