整理总结了一下文档内容,方便自己查阅~
一、RxSwift可以做什么?
-
点击方法TargetAction:
button.rx.tap.subscrible(onNext:{...})
-
代理Delegate:
scrollView.rx.contentOffset .subscrible(onNext:{ contentOffset in ...})
-
闭包回调Block:
URLSession.shared.rx.data(request:URLRequest(url:url)) .subscrible(onNext{ data in ...}) .onError{ error in ...})
-
通知Notify:
NotificationCenter.default.rx .notification(.UIApplicationiWillEnterForeground) .subscrible(onNext:{ notification in ...})
-
多个任务之间有依赖关系:依次执行(用例见文档)
-
等待多个并发任务完成后处理:合并网络请求
Observable.zip(API.1(...), API.2(...)) .subscrible(onNext:{(res1, res2) in ...})
例如:
valid = field.rx.text.orEmpty.map{$0.count >= 6}
.share(replay:1) // 多个地方使用时共享(而不是另外创建)
valid.bind(to: button.rx.isEnable)
valid3 = Observable.combineLatest(valid1, valid2){$0 && $1} // 合并
.share(replay:1)
.disposed(by: disposBag) // disposBag管理绑定的生命周期
二、RxSwift核心
例如:
text = field.rx.text.orEmpty.asObservable() // text是Observable<String>
valid = text.map{ $0.characters.count >= 6} // valid是Observable<Bool>、map是Operator
observer = tipsLb.rx.isHidden // Observer<Bool>
disposable = valid
.subscribleOn(MainScheduler.instance) // Scheduler
.observeOn(MainSchedule.instance)
.bind(to: observer)
disposable.dispose() // 解绑
三、Observable序列
所有事物皆序列:
Observable<Double> // 温度
Observable<onePieceEpisode> // 海贼王
Observable<JSON> // json
Observable<void> // 回调
最直接的创建方式:Observable.create
number: Observable<Int> =
Observable.create{ observer -> Disposable in // 参数 -> 返回类型
observer.onNext(0)
...
observer.onNext(n)
observer.onCompleted() // 表示已经全部生产,没有更多元素了
return Disposable.creat()
}
四、Observable特征序列
-
Single =
Observable.asSignle()
:只发出一个元素/Error -
Completable:一个Completed/Error
-
Maybe =
Observable.asMaybe()
:一个元素/completed/Error以上3不像Observable可发出多个元素,也不共享
-
Driver:不会Error 且 mainThread监听 (可简化UI层代码,解决失败不能try again,后台返回,多次请求)
-
Signal:与Driver相反,但不会对新观察者回放上一个元素(Driver会,不适用于点击事件)
-
ControlEvent:UI控件产生事件,无Error,mainThread订阅监听
以上3共享
五、Observer观察者
响应事件的都是观察者
RxSwift已实现的:
view.isHidden
button.isEnable
label.text
imageView.image
- …
最基本的创建方式:Observable.subscrible
tap.subscribe(onNext: { [weak self] in
self?.showAlert()
}, onError: { error in
print("发生错误: \(error.localizedDescription)")
}, onCompleted: {
print("任务完成")
})
特征观察者:
- AnyObservable:可描述任意一种观察者(定义一个回调,在subscrible中执行)详情
- Binder:详情
- 不处理Error(测试环境:执行
fataError
,发布环境:打印ErrorLog) - 确保绑定都在给定
Scheduler
上执行(默认:MainScheduler
)
- 不处理Error(测试环境:执行
注:
Observer监听到
error事件(onError:
)就会停止监听!!!
六、Observable & Observer
既是可监听序列 也是 观察者,如:field.text
/switch.on
/segmentedControl
选中/datePick
选中/…
RxSwift已定义的辅助类型,它们既是可监听序列也是观察者:
- AsyncSubject:事件完成后只发出最后一个元素/Error(即使是先订阅后产生的)
- PblishSubject:只收订阅后的元素
- ReplaySubject:会发送订阅前的元素,可以设置前n个/前一段时间的
- BehaviorSubject:订阅时,发送最新的元素/Error
- ControlProperty:UI控件属性,无Error,
mainThread
订阅监听(同ControlEvent)
七、Operator操作符
创建序列/组合原有序列
filter过滤:filter{ age in age >= 18 }
map转换:map{ Model.init }
(JSON -> Model)
Zip配对:Zip{ hamburg, frechFries }
(As, Bs -> {A, B})
forEach遍历:同for in
sorted排序:sorted{ student1, student2 in student1.score > student2.score}
。。。
Rx提供了充分的操作符来帮我们创建序列(操作符列表),当然如果内置的无法满足也可以自定义。选择操作符可以参考决策树
如何使用操作符:直接调用实例方法/静态方法
// 1.温度过滤
// 温度
let rxTemperature: Observable<Double> = ...
// filter 操作符
rxTemperature.filter { temperature in temperature > 33 }
.subscribe(onNext: { temperature in
print("高温:\(temperature)度")
})
.disposed(by: disposeBag)
// 2.解析JSON
// JSON
let json: Observable<JSON> = ...
// map 操作符
json.map(Model.init)
.subscribe(onNext: { model in
print("取得 Model: \(model)")
})
.disposed(by: disposeBag)
// 3.成套餐
// 汉堡
let rxHamburg: Observable<Hamburg> = ...
// 薯条
let rxFrenchFries: Observable<FrenchFries> = ...
// zip 操作符
Observable.zip(rxHamburg, rxFrenchFries)
.subscribe(onNext: { (hamburg, frenchFries) in
print("取得汉堡: \(hamburg) 和薯条:\(frenchFries)")
})
.disposed(by: disposeBag)
八、Disposable可被清除的资源
Disposable可被清除的资源
-
单独清除:
var disposable: Disposable? // 属性 self.disposable = field.rx.text.subscrible{ onNext:{...} } self.disposable.dispose() // 如:dismiss时
-
清除包:
var disposeBag: DisposableBag() // 属性 ....disposed(by: disposeBag) // 通过包清除 self.disposeBag = DisposBag() // 如:dealloc时
-
takeUntil:
....takeUnitl{ self.rx.deallocated } // dealloc时清除
例:
九、Scheduler调度器
控制任务在哪个线程或队列运行
如:
let rxData: Observable<Data> = ...
rxData
.subscribleOn(ConcurrentDispatchQueueScheduler(qos: .userInitiated)) // subscribleOn 设置`序列构建函数`在哪执行
// observeOn 设置在哪个线程监听
.observeOn(MainScheduler.asyncInstance) // 异步事件
//.observeOn(MianScheduler.instance) // 异步事件
.subscrible(onNext:{ [weak self] data in
self?.data = data
})
.disposed(by: disposeBag)
派发队列DispatchQueue:
- 主线程:MainScheduler
- 串行:SerialDsipatchQueueScheduler
- 并行:ConcurrentDispatchQueueScheduler
- OperationQueueScheduler抽象了
NSOperationQueue
,具备其一些特点,如:可以设置maxConcurrentOperationCount
控制同时执行并发任务的最大数量
十、防止Error后序列终止
ErrorHanding错误处理:
-
retry重试:
-
重试n次:
let rxJson: Observable<JSON> = ... rxJson .retry(3) // 重试3次 .subscribe(onNext: { json in print("取得 JSON 成功: \(json)") }, onError: { error in print("取得 JSON 失败: \(error)") // 3次后仍失败,将错误抛出 }) .disposed(by: disposeBag)
-
n秒后重试:
let retryDelay: Double = 5 // 延时 5 秒后重试 rxJson .retryWhen { (rxError: Observable<Error>) -> Observable<Int> in return Observable.timer(retryDelay, scheduler: MainScheduler.instance) } .subscribe(...) .disposed(by: disposeBag)
-
结合1.2.:失败后n秒重试,最多重试n次
let maxRetryCount = 4 // 最多重试 4 次 let retryDelay: Double = 5 // 重试延时 5 秒 rxJson .retryWhen { (rxError: Observable<Error>) -> Observable<Int> in return rxError.flatMapWithIndex { (error, index) -> Observable<Int> in guard index < maxRetryCount else { return Observable.error(error) } return Observable<Int>.timer(retryDelay, scheduler: MainScheduler.instance) } } .subscribe(...) .disposed(by: disposeBag)
-
-
catchError恢复:Error时,用1或n个备用元素代替
return network(query).catchErrorJustReturn([])
-
Return包装结果:
public enum Result<Success, Failure> where Failure : Error { case success(Success) case failure(Failure) } return network(query) .map(Result.success) .cathError( error in // 将错误事件被包装成了 Result.failure(Error) 元素 Observable.just(Result.failure(error)) )
-
materialize操作符进行处理:详情
十一、冷热信号
建议将其视为序列的属性,而不是单独的类型,因为它们是用同样的抽象来表示的,完全符合它们,可观察的序列Observable sequence
热信号 | 冷信号 |
---|---|
是序列 | 是序列 |
无论是否有观察者订阅,都使用资源(产生热能) | 观察者订阅之前,不使用资源(不产生热能) |
变量/属性/常量,点击坐标,鼠标坐标,UI控件值,当前时间… | 异步操作,HTTP连接,TCP连接,流… |
通常包含N个元素 | 通常包含1个元素 |
无论是否有观察者订阅,都会生成序列元素 | 晋档有订阅的观察者时才产生序列元素 |
序列计算资源通常在所有订阅的观察者之间共享 | 通常为每个订阅的观察者分配计算资源 |
通常有状态 | 通常无状态 |
参考: