Swift - RxSwift的使用詳解3(Observable介紹、創建可觀察序列)

三、Observable 介紹

Observable 作為 Rx 的根基,我們首先對它要有一些基本的了解。

1,Observable<T>

  • Observable<T> 這個類就是Rx 框架的基礎,我們可以稱它為可觀察序列。它的作用就是可以異步地產生一系列的 Event(事件),即一個 Observable<T> 對象會隨著時間推移不定期地發出 event(element : T) 這樣一個東西。
  • 而且這些 Event 還可以攜帶數據,它的泛型 <T> 就是用來指定這個Event攜帶的數據的類型。
  • 有了可觀察序列,我們還需要有一個Observer(訂閱者)來訂閱它,這樣這個訂閱者才能收到 Observable<T> 不時發出的 Event

2,Event

查看 RxSwift 源碼可以發現,事件 Event 的定義如下:

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
}

可以看到 Event 就是一個枚舉,也就是說一個 Observable 是可以發出 3 種不同類型的 Event 事件:

  • nextnext事件就是那個可以攜帶數據 <T> 的事件,可以說它就是一個“最正常”的事件。
  • errorerror 事件表示一個錯誤,它可以攜帶具體的錯誤內容,一旦 Observable 發出了 error event,則這個 Observable 就等于終止了,以后它再也不會發出 event 事件了。
  • completedcompleted 事件表示Observable 發出的事件正常地結束了,跟 error 一樣,一旦 Observable 發出了 completed event,則這個 Observable 就等于終止了,以后它再也不會發出 event 事件了。

3,Observable 與 Sequence比較

(1)為更好地理解,我們可以把每一個 Observable 的實例想象成于一個 Swift 中的 Sequence

  • 即一個 Observable(ObservableType)相當于一個序列 Sequence(SequenceType)
  • ObservableType.subscribe(_:)方法其實就相當于 SequenceType.generate()

(2)但它們之間還是有許多區別的:

  • Swift 中的 SequenceType 是同步的循環,而 Observable是異步的。
  • Observable 對象會在有任何 Event 時候,自動將 Event作為一個參數通過ObservableType.subscribe(_:)發出,并不需要使用 next方法。

四、創建 Observable 序列

我們可以通過如下幾種方法來創建一個 Observable序列

1,just() 方法

(1)該方法通過傳入一個默認值來初始化。

(2)下面樣例我們顯式地標注出了 observable 的類型為 Observable<Int>,即指定了這個 Observable所發出的事件攜帶的數據類型必須是 Int 類型的。

let observable = Observable<Int>.just(5)

2,of() 方法

(1)該方法可以接受可變數量的參數(必需要是同類型的)

(2)下面樣例中我沒有顯式地聲明出 Observable 的泛型類型,Swift 也會自動推斷類型。

let observable = Observable.of("A", "B", "C")

3,from() 方法

(1)該方法需要一個數組參數。

(2)下面樣例中數據里的元素就會被當做這個 Observable 所發出 event攜帶的數據內容,最終效果同上面餓 of()樣例是一樣的。

let observable = Observable.from(["A", "B", "C"])

4,empty() 方法

該方法創建一個空內容的 Observable 序列。

let observable = Observable<Int>.empty()

5,never() 方法

該方法創建一個永遠不會發出 Event(也不會終止)的 Observable 序列。

let observable = Observable<Int>.never()

6,error() 方法

該方法創建一個不做任何操作,而是直接發送一個錯誤的 Observable 序列。

enum MyError: Error {
    case A
    case B
}
         
let observable = Observable<Int>.error(MyError.A)

7,range() 方法

(1)該方法通過指定起始和結束數值,創建一個以這個范圍內所有值作為初始值的Observable序列。

(2)下面樣例中,兩種方法創建的 Observable 序列都是一樣的。

//使用range()
let observable = Observable.range(start: 1, count: 5)
 
//使用of()
let observable = Observable.of(1, 2, 3 ,4 ,5)

8,repeatElement() 方法

該方法創建一個可以無限發出給定元素的 EventObservable 序列(永不終止)。

let observable = Observable.repeatElement(1)

9,generate() 方法

(1)該方法創建一個只有當提供的所有的判斷條件都為 true 的時候,才會給出動作的 Observable 序列。
(2)下面樣例中,兩種方法創建的 Observable 序列都是一樣的。

//使用generate()方法
let observable = Observable.generate(
    initialState: 0,
    condition: { $0 <= 10 },
    iterate: { $0 + 2 }
)
 
//使用of()方法
let observable = Observable.of(0 , 2 ,4 ,6 ,8 ,10)

10,create() 方法

(1)該方法接受一個 block 形式的參數,任務是對每一個過來的訂閱進行處理。

(2)下面是一個簡單的樣例。為方便演示,這里增加了訂閱相關代碼(關于訂閱我之后會詳細介紹的)。

//這個block有一個回調參數observer就是訂閱這個Observable對象的訂閱者
//當一個訂閱者訂閱這個Observable對象的時候,就會將訂閱者作為參數傳入這個block來執行一些內容
let observable = Observable<String>.create{observer in
    //對訂閱者發出了.next事件,且攜帶了一個數據"hangge.com"
    observer.onNext("hangge.com")
    //對訂閱者發出了.completed事件
    observer.onCompleted()
    //因為一個訂閱行為會有一個Disposable類型的返回值,所以在結尾一定要returen一個Disposable
    return Disposables.create()
}
 
//訂閱測試
observable.subscribe {
    print($0)
}

運行結果如下:

11,deferred() 方法

(1)該個方法相當于是創建一個 Observable 工廠,通過傳入一個 block 來執行延遲 Observable序列創建的行為,而這個 block 里就是真正的實例化序列對象的地方。

(2)下面是一個簡單的演示樣例:

//用于標記是奇數、還是偶數
var isOdd = true
 
//使用deferred()方法延遲Observable序列的初始化,通過傳入的block來實現Observable序列的初始化并且返回。
let factory : Observable<Int> = Observable.deferred {
     
    //讓每次執行這個block時候都會讓奇、偶數進行交替
    isOdd = !isOdd
     
    //根據isOdd參數,決定創建并返回的是奇數Observable、還是偶數Observable
    if isOdd {
        return Observable.of(1, 3, 5 ,7)
    }else {
        return Observable.of(2, 4, 6, 8)
    }
}
 
//第1次訂閱測試
factory.subscribe { event in
    print("\(isOdd)", event)
}
 
//第2次訂閱測試
factory.subscribe { event in
    print("\(isOdd)", event)
}

運行結果如下,可以看到我們兩次訂閱的得到的 Observable 是不一樣的:

12,interval() 方法

(1)這個方法創建的 Observable 序列每隔一段設定的時間,會發出一個索引數的元素。而且它會一直發送下去。

(2)下面方法讓其每 1 秒發送一次,并且是在主線程(MainScheduler)發送。

let observable = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
observable.subscribe { event in
    print(event)
}

運行結果如下:

13,timer() 方法

(1)這個方法有兩種用法,一種是創建的 Observable序列在經過設定的一段時間后,產生唯一的一個元素。

//5秒種后發出唯一的一個元素0
let observable = Observable<Int>.timer(5, scheduler: MainScheduler.instance)
observable.subscribe { event in
    print(event)
}

運行結果如下:

(2)另一種是創建的 Observable 序列在經過設定的一段時間后,每隔一段時間產生一個元素。

//延時5秒種后,每隔1秒鐘發出一個元素
let observable = Observable<Int>.timer(5, period: 1, scheduler: MainScheduler.instance)
observable.subscribe { event in
    print(event)
}

運行結果如下:

RxSwift使用詳解系列
原文出自:www.hangge.com轉載請保留原文鏈接

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,702評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,143評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,553評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,620評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,416評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,940評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,024評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,170評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,709評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,597評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,291評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,029評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,407評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,663評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,403評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,746評論 2 370

推薦閱讀更多精彩內容