- 觀察者模式:KVO、通知
- 被觀察者:發(fā)出一個事件
- 觀察者/訂閱者:對被觀察者對象進(jìn)行響應(yīng)
RXSwift:把程序中每一個操作看成一個事件。例如:點(diǎn)擊事件,filed文本改變、請求完成等,每一個事件源可以看成一個管道,也就是sequence(序列)。
例如:testFiled文本改變時,就會不斷的發(fā)出事件,就會從他的這個sequence管道中不斷流出,只需監(jiān)聽這個sequence(可監(jiān)聽序列),每流出一個事件就做相應(yīng)的處理。
總結(jié):將事件包裝在一個序列里面,我們只需要監(jiān)聽從序列里面不斷流出的事件即可。
序列:
Observable:對觀察者發(fā)送全部的元素,無論觀察者是何時進(jìn)行訂閱的。ReplaySubject會受bufferSize影響。
創(chuàng)建一個序列的一般方法偽代碼:
let json: Observable<泛型約束,事件類型:如JSON、[String:AnyHasble]、Data、Int> = Observable.create { observer -> Disposable in
if (a) {
observer.onNext(0)
}else if (b) {
observer.onNext(1)
observer.onCompleted()
}else {
observer.onError(error!)
}
return Disposables.create()
}
特征序列:
特征序列一:
不會共享附加作用:
主要用于數(shù)據(jù)請求、業(yè)務(wù)邏輯上:
- Single: 發(fā)出一個元素,或一個 error 事件
- Completable: 發(fā)出零個元素;發(fā)出一個 completed 事件或者一個 error 事件
- Maybe: 發(fā)出一個元素或者一個 completed 事件或者一個 error 事件
特征序列二:
共享附加作用
不會產(chǎn)生 error 事件
一定在MainScheduler監(jiān)聽(主線程監(jiān)聽)
主要用于UI事件的生成序列上:
- Driver:會對新觀察者回放(重新發(fā)送)上一個元素。 .asDriver(); event.drive(onNext: newObserver)
狀態(tài)序列一般選用 Driver 這個類型 - Signal:不會對新觀察者回放上一個元素。 .asSignal(); event.emit(onNext: newObserver)
事件序列一般選用 Signal 這個類型。
Observer 觀察者/訂閱者:用來監(jiān)聽事件,然后對這個事件做出響應(yīng)。
subscribe(onNext: { [weak self] in
self?.showAlert()
}, onError: { error in
print("發(fā)生錯誤: \(error.localizedDescription)")
}, onCompleted: {
print("任務(wù)完成")
})
特征觀察者:
- AnyObserver:可以用來描敘任意一種觀察者。(也就是可以把序列上的直接觀察者.subscribe(onNext:)或者.bind(to:)提取封裝出來,轉(zhuǎn)化成.subscribe(observer)或者.bind(to: observer))
- Binder:UI觀察者;1、不會處理錯誤事件;2、確保綁定都是在給定 Scheduler 上執(zhí)行(默認(rèn) MainScheduler)
let observer: Binder<Bool> = Binder(usernameValidOutlet) { (view, isHidden) in
view.isHidden = isHidden
}
.bind(to: observer) <==等價于==> .bind(to: usernameValidOutlet.rx.isHidden)
既是可監(jiān)聽序列Observable也是觀察者Observer, 既可發(fā)出事件也可監(jiān)聽事件。
例如:textField的當(dāng)前文本。
// 作為可監(jiān)聽序列 ----它可以看成是由用戶輸入,而產(chǎn)生的一個文本序列
let observable = textField.rx.text
observable.subscribe(onNext: { text in show(text: text) })
// 作為觀察者 ----由外部文本序列,來控制當(dāng)前textField顯示內(nèi)容的觀察者
let observer = textField.rx.text
text.bind(to: observer)
輔助類型:它們既是可監(jiān)聽序列也是觀察者??梢詭徒M更準(zhǔn)確的描述事物的特征:
- AsyncSubject:對觀察者發(fā)送的全部的元素中,無論觀察者是何時進(jìn)行訂閱的,發(fā)出最后一個元素(僅僅只有最后一個元素)?;虻谝粋€onCompleted/onError元素(序列結(jié)束)。
- PublishSubject:對觀察者發(fā)送訂閱后產(chǎn)生的元素,而在訂閱前發(fā)出的元素將不會發(fā)送給觀察者。
- ReplaySubject:對觀察者發(fā)送”全部“(受bufferSize影響)的元素,無論觀察者是何時進(jìn)行訂閱的。有的只會將最新的 n 個元素發(fā)送給觀察者,有的只會將限制時間段內(nèi)最新的元素發(fā)送給觀察者(具體元素個數(shù)根據(jù)bufferSize設(shè)置)。
- BehaviorSubject:首先會將最新的元素發(fā)送出來,如果不存在最新的元素,就發(fā)出默認(rèn)元素。然后將隨后產(chǎn)生的元素發(fā)送出來。 (先發(fā)訂閱前的最新的一個元素,沒有則發(fā)送默認(rèn)【BehaviorSubject(value: "默認(rèn)元素")】,然后再發(fā)送之后的元素)
操作符:
對序列中的事件做相應(yīng)的操作(如:遍歷、filter過濾、map轉(zhuǎn)換、zip配對),生成新的序列。
Disposable - 可被清除的資源
一個序列如果發(fā)出了 error 或者 completed 事件,那么所有內(nèi)部資源都會被釋放。
- 清除包(DisposeBag) 或者 takeUntil 操作符 來管理訂閱的生命周期。
- 清除包被釋放的時候,清除包內(nèi)部所有可被清除的資源(Disposable)都將被清除。
self.disposable = textField.rx.text.orEmpty.subscribe(onNext: { text in print(text) })
self.disposable?.dispose()
調(diào)用 dispose 方法后,訂閱將被取消,并且內(nèi)部資源都會被釋放。
_ = usernameValid.takeUntil(self.rx.deallocated).bind(to: passwordOutlet.rx.isEnabled)//訂閱一直持續(xù)到控制器的dealloc事件產(chǎn)生為止。
使用takeUntil操作符:實(shí)現(xiàn)自動取消訂閱的方法
Schedulers - 調(diào)度器
- subscribeOn:數(shù)據(jù)序列的構(gòu)建函數(shù)在哪個 Scheduler 上運(yùn)行。
- observeOn:在哪個 Scheduler 監(jiān)聽這個數(shù)據(jù)序列。
- MainScheduler 代表主線程。
- SerialDispatchQueueScheduler 抽象了串行 DispatchQueue。
- ConcurrentDispatchQueueScheduler 抽象了并行 DispatchQueue。
- OperationQueueScheduler 抽象了 NSOperationQueue。