RxSwift 核心內(nèi)容
image
- Observable - 產(chǎn)生事件
- Observer - 響應(yīng)事件
- Operator - 創(chuàng)建變化組合事件
- Disposable - 管理綁定(訂閱)的生命周期
- Schedulers - 線程隊(duì)列調(diào)配
1.0桑驱、 Observable - 可監(jiān)聽序列
所有的實(shí)物都是序列
/** Observable 可以用于描述元素異步產(chǎn)生的序列*/
Observable<Double> // 溫度,把溫度看作是一個(gè)序列
Observable<JSON> //JSON,把網(wǎng)絡(luò)請(qǐng)求的返回的 JSON 看作是一個(gè)序列
Observable<Void> //任務(wù)回調(diào),把任務(wù)回調(diào)看作是一個(gè)序列
/**框架已經(jīng)幫我們創(chuàng)建好了許多常用的序列启盛。
例如:button的點(diǎn)擊走孽,textField的當(dāng)前文本焙格,switch的開關(guān)狀態(tài)载佳,slider的當(dāng)前數(shù)值等等演顾,而另外一些重抖,則需要我們自己創(chuàng)建*/
//自定義的序列
let numbers: Observable<Int> = Observable.create { observer -> Disposable in
observer.onNext(0)
observer.onNext(1)
observer.onNext(2)
observer.onNext(3)
observer.onNext(4)
observer.onNext(5)
observer.onNext(6)
observer.onNext(7)
observer.onNext(8)
observer.onNext(9)
observer.onCompleted()
return Disposables.create()
}
1.1楚午、在閉包回調(diào)中的使用
typealias JSON = Any
let json: Observable<JSON> = Observable.create { (observer) -> Disposable in
let task = URLSession.shared.dataTask(with: ...) { data, _, error in
guard error == nil else {
observer.onError(error!)
return
}
guard let data = data,
let jsonObject = try? JSONSerialization.jsonObject(with: data, options: .mutableLeaves)
else {
observer.onError(DataError.cantParseJSON)
return
}
observer.onNext(jsonObject)
observer.onCompleted()
}
task.resume()
return Disposables.create { task.cancel() }
}
json
.subscribe(onNext: { json in
print("取得 json 成功: \(json)")
}, onError: { error in
print("取得 json 失敗 Error: \(error.localizedDescription)")
}, onCompleted: {
print("取得 json 任務(wù)成功完成")
})
.disposed(by: disposeBag)
2.0宴偿、Observer - 觀察者
觀察者 是用來(lái)監(jiān)聽事件湘捎,然后它需要這個(gè)事件做出響應(yīng)。例如:彈出提示框就是觀察者窄刘,它對(duì)點(diǎn)擊按鈕這個(gè)事件做出響應(yīng)
Observer<Double>
Observer<JSON>
Observer<Void>
2.1窥妇、創(chuàng)建觀察者
/**框架已經(jīng)幫我們創(chuàng)建好了許多常用的觀察者。例如:view 是否隱藏娩践,button 是否可點(diǎn)擊活翩, label 的當(dāng)前文本,imageView 的當(dāng)前圖片等等翻伺,而另外一些也要我們自己創(chuàng)建*/
//自定義觀察者
tap.subscribe(onNext: { [weak self] in
self?.showAlert()
}, onError: { error in
print("發(fā)生錯(cuò)誤: \(error.localizedDescription)")
}, onCompleted: {
print("任務(wù)完成")
})
3.0材泄、即是可監(jiān)聽序列,又是觀察者
/**例如:textField的當(dāng)前文本吨岭。它可以看成是由用戶輸入拉宗,而產(chǎn)生的一個(gè)文本序列*/
// 作為可監(jiān)聽序列
let observable = textField.rx.text
observable.subscribe(onNext: { text in show(text: text) })
// 作為觀察者
let observer = textField.rx.text
let text: Observable<String?> = ...
text.bind(to: observer)
3.1、框架中定義的其他即可以是觀察者辣辫,又可以是監(jiān)聽序列的輔助類型
- AsyncSubject
- PublishSubject
- ReplaySubject
- BehaviorSubject
- ControlProperty
4.0旦事、Operator - 操作符
image
操作符可以幫助大家創(chuàng)建新的序列,或者變化組合原有的序列急灭,從而生成一個(gè)新的序列姐浮。
filter - 過(guò)濾
image
map - 轉(zhuǎn)換
image
zip - 配對(duì)
image
4.1、操作符的使用
// 溫度
let rxTemperature: Observable<Double> = ...
// filter 操作符
rxTemperature.filter { temperature in temperature > 33 }
.subscribe(onNext: { temperature in
print("高溫:\(temperature)度")
})
.disposed(by: disposeBag)
// JSON
let json: Observable<JSON> = ...
// map 操作符
json.map(Model.init)
.subscribe(onNext: { model in
print("取得 Model: \(model)")
})
.disposed(by: disposeBag)
// 漢堡
let rxHamburg: Observable<Hamburg> = ...
// 薯?xiàng)l
let rxFrenchFries: Observable<FrenchFries> = ...
// zip 操作符
Observable.zip(rxHamburg, rxFrenchFries)
.subscribe(onNext: { (hamburg, frenchFries) in
print("取得漢堡: \(hamburg) 和薯?xiàng)l:\(frenchFries)")
})
.disposed(by: disposeBag)
5.0化戳、Disposable - 可被清除的資源
image
var disposable: Disposable?
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.disposable = textField.rx.text.orEmpty
.subscribe(onNext: { text in print(text) })
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.disposable?.dispose()
}
5.1单料、DisposeBag - 清除包
image
var disposeBag = DisposeBag()
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
textField.rx.text.orEmpty
.subscribe(onNext: { text in print(text) })
.disposed(by: self.disposeBag)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.disposeBag = DisposeBag()
}
5.2埋凯、takeUntil - 自動(dòng)取消訂閱
override func viewDidLoad() {
super.viewDidLoad()
...
_ = usernameValid
.takeUntil(self.rx.deallocated)
.bind(to: passwordOutlet.rx.isEnabled)
_ = usernameValid
.takeUntil(self.rx.deallocated)
.bind(to: usernameValidOutlet.rx.isHidden)
_ = passwordValid
.takeUntil(self.rx.deallocated)
.bind(to: passwordValidOutlet.rx.isHidden)
_ = everythingValid
.takeUntil(self.rx.deallocated)
.bind(to: doSomethingOutlet.rx.isEnabled)
_ = doSomethingOutlet.rx.tap
.takeUntil(self.rx.deallocated)
.subscribe(onNext: { [weak self] in self?.showAlert() })
}
6.0、Schedulers - 調(diào)度器
Schedulers 是 Rx 實(shí)現(xiàn)多線程的核心模塊扫尖,它主要用于控制任務(wù)在哪個(gè)線程或隊(duì)列運(yùn)行白对。
//正常gcd,后臺(tái)取得數(shù)據(jù),主線程處理結(jié)果
DispatchQueue.global(qos: .userInitiated).async {
let data = try? Data(contentsOf: url)
DispatchQueue.main.async {
self.data = data
}
}
//RxSwift 來(lái)實(shí)現(xiàn)
let rxData: Observable<Data> = ...
rxData
.subscribeOn(ConcurrentDispatchQueueScheduler(qos: .userInitiated))
.observeOn(MainScheduler.instance)
.subscribe(onNext: { [weak self] data in
self?.data = data
})
.disposed(by: disposeBag)
MainScheduler
MainScheduler 代表主線程换怖。如果你需要執(zhí)行一些和 UI 相關(guān)的任務(wù)甩恼,就需要切換到該 Scheduler 運(yùn)行。
SerialDispatchQueueScheduler
SerialDispatchQueueScheduler 抽象了串行 DispatchQueue沉颂。如果你需要執(zhí)行一些串行任務(wù)条摸,可以切換到這個(gè) Scheduler 運(yùn)行。
ConcurrentDispatchQueueScheduler
ConcurrentDispatchQueueScheduler 抽象了并行 DispatchQueue铸屉。如果你需要執(zhí)行一些并發(fā)任務(wù)钉蒲,可以切換到這個(gè) Scheduler 運(yùn)行。
OperationQueueScheduler
OperationQueueScheduler 抽象了 NSOperationQueue彻坛。
它具備 NSOperationQueue 的一些特點(diǎn)顷啼,例如,你可以通過(guò)設(shè)置 maxConcurrentOperationCount昌屉,來(lái)控制同時(shí)執(zhí)行并發(fā)任務(wù)的最大數(shù)量钙蒙。
7.0、Error Handling - 錯(cuò)誤處理
retry - 重試
// 請(qǐng)求 JSON 失敗時(shí)间驮,立即重試躬厌,
// 重試 3 次后仍然失敗,就將錯(cuò)誤拋出
let rxJson: Observable<JSON> = ...
rxJson
.retry(3)
.subscribe(onNext: { json in
print("取得 JSON 成功: \(json)")
}, onError: { error in
print("取得 JSON 失敗: \(error)")
})
.disposed(by: disposeBag)
retryWhen - 重試延遲