Observables
Observables
是Rx
的核心鞋囊,本節(jié)將花點時間學習如何創(chuàng)建和使用Observables
。在RxSwift
中溜腐,Observables
瓜喇、Observables sequence
和sequence
代表相同的意思,在RxSwift
的世界里望众,任何事物都是序列伞辛。observable
也是序列,它可以產(chǎn)生事件甘耿,事件可以包含值佳恬。
Observables三種狀態(tài)和生命周期
Observables
有三種狀態(tài)分別是next
于游、error
和completed
。下面使用圓珠圖(marble diagram)理解Observables
的生命周期头谜。
上圖中從左到右的箭頭代表時間柱告,線上的圓珠代表序列事件元素。隨著時間的推移線上的元素會被依次發(fā)射葵袭。
observable
發(fā)射元素產(chǎn)生next
事件。
另一張圓珠圖乖菱,它存在一個結束線坡锡。
此observable
發(fā)射三個tap
事件,當結束時會發(fā)個completed
事件作為序列的結束標志窒所。例如:tap
所在的界面銷毀鹉勒。在observable
結束后不再發(fā)送任何事件,這種結束方式屬于正常終止吵取。
另外禽额,存在一種非正常方式結束序列,如出現(xiàn)錯誤時皮官,如下面這張圖脯倒。
當錯誤發(fā)送時藻丢,observable
發(fā)射error
事件此時序列終止不再發(fā)射任何事件悠反。
回顧一下上面三張圖:
隨著時間推移序列會根據(jù)元素依次發(fā)送next
事件斋否,兩種情況導致序列結束如叼,第一穷劈,發(fā)生錯誤發(fā)射error
事件序列終止歇终,第二评凝,發(fā)射completed
事件序列終止奕短。序列一旦終止就不會再發(fā)射任何事件。
在Swift
中谬返,事件是枚舉類型的結構如下:
/// 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
攜帶一個泛型Element
。 - ②:
error
攜帶一個Swift.Error
實例對象莉擒。 - ③:
completed
表示序列結束不攜帶值涨冀。
創(chuàng)建Observables
了解了Observables
概念接下學習如何創(chuàng)建和使用Observables
廷支。
RxSwift
提供多種方式創(chuàng)建Observables
栓辜。例如:of
, just
, from
, empty
, never
和range
等藕甩。
just
: 創(chuàng)建單個事件的序列僵娃。of
: 創(chuàng)建多個事件的序列腋妙。from
: 通過數(shù)組創(chuàng)建多個事件的序列匙睹。empty
創(chuàng)建一個空的序列痕檬,只發(fā)射completed
事件送浊。never
創(chuàng)建一個不發(fā)射事件也不會結束的序列。range(start, count)
:創(chuàng)建包含多個事件的序列闭树。
// 1. 創(chuàng)建Observables
example(of: "just of from") {
// 1
let one = 1
let two = 2
let three = 3
// 2
let observable1 = Observable.just(one)
// 3
let observable2 = Observable.of(one, two, three)
let observable3 = Observable.of([one, two, three]) // [Int]
// 4
let observable4 = Observable.from([one, two, three])
let observable5 = Observable<Void>.empty()
let observable6 = Observable<Any>.never()
let observable7 = Observable.range(start: 1, count: 5)
}
- 定義三個常量。
- 使用
just
創(chuàng)建只有一個元素的序列捏肢,此時序列類型為Observable<Int>
饥侵。 - 使用
of
創(chuàng)建序列躏升,注意Observable2
是Observable<Int>
膨疏,而observable3
是Observable<[Int]>
類型 佃却。 - 使用
from
創(chuàng)建序列饲帅,此時接收的參數(shù)是數(shù)組類型灶泵。注意:與of
的區(qū)別赦邻。
除了前面的創(chuàng)建方式還可以使用create
創(chuàng)建序列惶洲。
// Create方法湃鹊,內(nèi)部有一個observer
example(of: "Create") {
// 1
let disposeBag = DisposeBag()
// 2
Observable<String>.create { observer in
observer.onNext("1")
observer.onCompleted()
observer.onNext("2")
// 3
return Disposables.create()
}
// 4
.subscribe(
onNext: {print($0)},
onError: {print($0)},
onCompleted: {print("Completed")},
onDisposed: {print("Disposed")}
)
// 5
.disposed(by: disposeBag)
}
- 創(chuàng)建一個
DisposeBag
對象,用于管理序列 -
create
方法參數(shù)是一個逃逸閉包參數(shù)為AnyObserver
返回值Disposable
類型。AnyObserver
是通用類型用來將值添加到序列中芯义,在將來發(fā)射給訂閱者扛拨。 - 返回
disposable
代表訂閱,Disposables.create()
創(chuàng)建了一個空的disposable
央渣。 - 通過
subscribe
訂閱芽丹,運行結果你會發(fā)現(xiàn)沒有輸出2
拔第,因為在onNext("2")
之前懈涛,已經(jīng)發(fā)送completed
事件序列終止泳猬。 - 添加到
bag
中暂殖。
訂閱序列
訂閱序列使用.subscribe
方法踩窖。直接看示例代碼:
// 訂閱
example(of: "subscrible") {
let one = 1
let two = 2
let three = 3
// 1
let observable = Observable.from([one ,two, three])
// 2 第一種
observable.subscribe { event in
print(event) // 輸出事件
if let element = event.element {
print(element)
}
}
// 3 另一種方式
observable.subscribe(onNext: { (element) in
print(element)
}, onError: { (error) in
print(error)
}, onCompleted: {
print("completed")
}, onDisposed: {
print("disposed")
})
}
- 創(chuàng)建有多個元素的序列洋腮。
- 使用
func subscribe(_ on: @escaping (Event<Int>) -> Void) -> Disposable
方法訂閱序列啥供,逃逸閉包參數(shù)是Int
類型的事件伙狐。方法返回值是Disposable
罢防。Disposable
稍后會學到咒吐。閉包中參數(shù)是事件恬叹,通過事件的可選值element
參數(shù)獲取值。 - 另一個方法相對方便嗽测,直接可以獲取到事件的值唠粥。注意:
onError
大莫、onCompleted
和onDisposed
是可選的只厘。
清除和終止
在Observable
為被訂閱時羔味,不會發(fā)射任何事件赋元,當出現(xiàn)錯誤或結束時才會終止。不過狠毯,也可以通過清除訂閱來終止序列嫡良。
每一個訂閱者都存在一個dispose
方法皆刺,當調(diào)用該方法時會清除訂閱者羡蛾。示例代碼:
// dispose 用于回收,防止內(nèi)存泄露
example(of: "dispose") {
let observable = Observable.of("A", "B", "C")
let subscription = observable.subscribe {event in
print(event)
}
subscription.dispose()
}
example(of: "DisposeBag") {
let disposeBag = DisposeBag()
Observable.of("A", "B", "C")
.subscribe {
print($0)
}
.disposed(by: disposeBag)
}
-
DisposeBag
清除包浪藻,通過調(diào)用dispose
方法爱葵,取消訂閱并且釋放內(nèi)部資源萌丈。
三種特殊的Observable
-
Single
:不同于Observable
它只會發(fā)送next
或error
事件。Observable
通過調(diào)用asSingle
方法可以轉(zhuǎn)換成Single
度迂。
通常用于網(wǎng)絡下載或者讀取磁盤數(shù)據(jù)惭墓。
example(of: "Single") {
// 1
let disposeBag = DisposeBag()
// 2
enum FileError: Error {
case fileNotFound, unreadable, encodingFailed
}
// 3
func loadText(from name: String) -> Single<String> {
// 4
return Single.create { single in
let disposable = Disposables.create()
guard let path = Bundle.main.path(forResource: name, ofType: "txt") else {
single(.error(FileError.fileNotFound))
return disposable
}
guard let data = FileManager.default.contents(atPath: path) else {
single(.error(FileError.unreadable))
return disposable
}
guard let content = String(data: data, encoding: .utf8) else {
single(.error(FileError.encodingFailed))
return disposable
}
single(.success(content))
return disposable
}
}
loadText(from: "Copyright")
.subscribe {
switch $0 {
case .success(let str):
print(str)
case .error(let error):
print(error)
}
}
.disposed(by: disposeBag)
}
-
Completable
:只會發(fā)送completed
或error
事件毅人。只關心任務是否完成不關心返回值丈莺,類似Observable<Void>
-
Maybe
: 介于Completable
與Single
之間弛秋,只會發(fā)送一個元素。
本節(jié)是對RxSwift
中Observable
概念和使用的初步學習登失,循序漸進逐步深入學習深層次內(nèi)容。
小結
-
Observables
是什么馅巷?生命周期钓猬? -
Observables
創(chuàng)建方法有哪些敞曹? - 如何訂閱
Observable
? -
DisposeBag
是什么异雁?它的作用是什么?