RxSwift學(xué)習(xí)之Observable的新建、訂閱及取消訂閱
前言
我們?cè)?a target="_blank" href="http://www.dbjr.com.cn/article/124120.htm">前一篇基礎(chǔ)之上,本文將會(huì)介紹 RxSwift 中的 Observables 部分。
在 RxSwift 中 Observable 也被稱為 Observable Sequence、Sequence、Stream。Observable 會(huì)以異步的方式不斷的發(fā)射事件形成事件流,并且數(shù)據(jù)也會(huì)沿著事件流進(jìn)行傳播。下圖是事件流的圖像化表示:
其中從左到右的箭頭代表時(shí)間軸,而三個(gè)圓圈則構(gòu)成了可觀察序列。而整個(gè)過程會(huì)按照從左到右的順序。另外,事件可能在可觀察序列生命周期內(nèi)的任意時(shí)刻被觸發(fā)。
Observable 生命周期
上圖中的三個(gè)圓圈其實(shí)就是 RxSwift 中的 next 事件。除了 next 之外,RxSwift 中還有 completed 和 error 事件,而這兩者都意味事件流生命周期的總結(jié)。
completed 所表示的正常終結(jié):
error 所表示的異常終結(jié):
在源碼中這三類事件的定義如下:
/// Represents a sequence event. /// /// Sequence grammar: /// **next\* (error | completed)** public enum Event<Element> { /// Next element is produced. case next(Element) /// Sequence terminated with an error. case error(Swift.Error) /// Sequence completed successfully. case completed }
在代碼中,我們可以清晰的看到 next 事件會(huì)攜帶一個(gè)實(shí)例進(jìn)行傳播,error 事件會(huì)攜帶一個(gè) Error 實(shí)例,completed 則什么都不會(huì)攜帶。
新建 Observable
在所有 Observable 對(duì)象的創(chuàng)建方法中,最簡單的就是 just :
// 1 let one = 1 let two = 2 let three = 3 // 2 let observable: Observable<Int> = Observable<Int>.just(one)
作為類方法 just 所創(chuàng)建的 Observable 對(duì)象只會(huì)包含一個(gè)元素。但是大多數(shù)時(shí)候,Observable 對(duì)象在其生命周期內(nèi)會(huì)包含多個(gè)元素,而創(chuàng)建方法也很簡單:
let observable2 = Observable.of(one, two, three)
可能上面的代碼會(huì)給人一種誤導(dǎo),讓人覺得 observable2 中的數(shù)據(jù)可能是一個(gè)數(shù)組類型。不過好在我們可以通過下面的代碼進(jìn)行檢驗(yàn):
observable2.subscribe(onNext: { element in print(element) }) /* 打印結(jié)果: 1 2 3 */
而真正創(chuàng)建數(shù)組類型變量的方法是:
let observable3 = Observable.of([one, two, three]) observable3.subscribe(onNext: { element in print(element) }) /* 打印結(jié)果: [1, 2, 3] */
上面只是幾個(gè)常用的 Observable 創(chuàng)建方法,更多的內(nèi)容可以去查文檔和代碼。
訂閱 Observable
在日常 iOS 編程中,通知模式可以說是使用頻率相當(dāng)高的一個(gè)設(shè)計(jì)模式。我們通過 NotificationCenter 實(shí)現(xiàn)消息的廣播和訂閱。下面是一個(gè)典型的通知模式代碼用于處理 UIKeyboardDidChangeFrame 消息:
let observer = NotificationCenter.default.addObserver( forName: .UIKeyboardDidChangeFrame, object: nil, queue: nil ) { notification in // 閉包 }
RxSwift 中的訂閱操作也非常簡單,只需要調(diào)用 subscribe 方法就行了。不過與 NotificationCenter 機(jī)制不同的是,RxSwift 中每一個(gè)訂閱都是唯一的并沒有一個(gè)類似 default 這樣的全局單例對(duì)象。
更為重要的是,在沒有訂閱者的時(shí)候 Observable 對(duì)象不會(huì)發(fā)送通知。另外, Observable 對(duì)象實(shí)際上是一個(gè)序列,所以訂閱操作有點(diǎn)類似于反復(fù)調(diào)用 Swift 標(biāo)準(zhǔn)庫里中迭代器 Iterator 對(duì)象 next 函數(shù):
let sequence = 0..<3 var iterator = sequence.makeIterator() while let n = iterator.next() { print(n) } /* 打印結(jié)果: 0 1 2 */
不過 RxSwift 訂閱操作明顯比這個(gè)來的更直接,并且可以一次實(shí)現(xiàn)對(duì) next、error、completed 事件的的處理。一個(gè)簡單的訂閱操作示例:
let one = 1 let two = 2 let three = 3 let observable = Observable.of(one, two, three) observable.subscribe { event in print(event) }
上面代碼的訂閱操作非常簡單:打印出 observable 聲明周期內(nèi)的所有事件。正常情形下,它的結(jié)果如下:
next(1) next(2) next(3) completed
當(dāng)然,有時(shí)候我們可能只是需要 observable 所發(fā)射的數(shù)據(jù):
observable.subscribe { event in if let element = event.element { print(element) } } /* 打印結(jié)果: 1 2 3 */
又或者,我們需要對(duì)不同事件區(qū)別處理:
observable .subscribe( onNext: { element in print(element) }, onCompleted: { print("Completed") } )
取消訂閱并消除內(nèi)存泄漏
Observable 對(duì)象只有在存在訂閱的情形下才會(huì)進(jìn)行數(shù)據(jù)發(fā)送操作,而且會(huì)在 error 或 completed 事件觸發(fā)時(shí)結(jié)束其生命周期。但是,有時(shí)候我們可能需要手動(dòng)取消訂閱并提前終結(jié) Observable 對(duì)象的生命。
let observable = Observable.of("A", "B", "C") let subscription = observable.subscribe { event in print(event) }
上面代碼非常簡單這里就不再細(xì)訴了,這里我們直接來看取消訂閱的操作。其實(shí),取消訂閱的操作非常之簡單只需一行代碼:
subscription.dispose()
當(dāng)然,手動(dòng)對(duì)每一個(gè)訂閱對(duì)象進(jìn)行取消操作顯然是一件枯燥的工作。所以 RxSwift 為大家提供了一個(gè)更為簡單的方案。只需在訂閱時(shí)調(diào)用 .addDisposableTo() 添加一個(gè) DisposeBag 類型對(duì)象,我們就能在 DisposeBag 對(duì)象銷毀時(shí)取消所有綁定訂閱對(duì)象的取消動(dòng)作。
let disposeBag = DisposeBag() Observable.of("A", "B", "C") .subscribe { 3 print($0) } .addDisposableTo(disposeBag)
這里我們之所以需要進(jìn)行 DisposeBag 對(duì)象綁定或者手動(dòng)調(diào)用 dispose() 進(jìn)行取消訂閱操作,是因?yàn)槿绻贿@么做的話 Observable 對(duì)象在生命周期完結(jié)時(shí)會(huì)存在內(nèi)存泄漏的問題。
總結(jié)
本文只是簡單的介紹了 Observables 一些常見基礎(chǔ)內(nèi)容。這里還有很多更深入的內(nèi)容沒有介紹,例如:empty 和 never 類型的訂閱、使用 Create 實(shí)現(xiàn)自定義 Observable 以及 Error 類型的自定義實(shí)現(xiàn)。如果你有興趣的話,我強(qiáng)烈建議你查閱官方文檔和代碼。
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
Flutter iOS開發(fā)OC混編Swift動(dòng)態(tài)庫和靜態(tài)庫問題填坑
這篇文章主要為大家介紹了Flutter iOS OC 混編 Swift動(dòng)態(tài)庫和靜態(tài)庫問題填坑詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07Swift操作Quartz 2D進(jìn)行簡單的繪圖與坐標(biāo)變換的教程
這篇文章主要介紹了Swift操作Quartz 2D進(jìn)行簡單的繪圖與坐標(biāo)變換的教程,Quartz 2D是Core Graphics框架中的一個(gè)重要組件,經(jīng)常被Mac OS或和iOS開發(fā)者用來繪圖,需要的朋友可以參考下2016-04-04SwiftUI學(xué)習(xí)之state和Binding的區(qū)別淺析
這篇文章主要給大家介紹了關(guān)于SwiftUI學(xué)習(xí)之state和Binding區(qū)別的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03Swift 3.0將UILabel數(shù)字顏色設(shè)置為紅色的方法
這篇文章主要介紹了關(guān)于在Swift中將UILabel數(shù)字顏色設(shè)置為紅色的方法,文中給出了詳細(xì)的示例代碼,相信對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來一起看看吧。2017-03-03在Swift中使用KVO的細(xì)節(jié)以及內(nèi)部實(shí)現(xiàn)解析(推薦)
這篇文章主要介紹了在Swift中使用KVO的細(xì)節(jié)以及內(nèi)部實(shí)現(xiàn)解析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07