RxSwift基础知识
RxSwift 是 ReactiveX 编程思想的一种实现,几乎每一种语言都会有那么一个 Rx[xxxx] 框架,比如RxSwift, RxJava,RxJS 等等。ReactiveX(Reactive Extensions)是通过可观察的流实现异步编程的一种API
Rx的基本概念
观察者模式 Observable:
对某些数据流(很广,可以是一些事件等)进行处理,使其变成可观察对象(Observable)序列,这样观察者(observer)就可以订阅这些序列
Observable 直译为可观察的,它在 RxSwift 起到了举足轻重的作用,在整个 RxSwift 的使用过程中你会经常与它打交道。如果你使用过 RAC ,它如同 Signal 一样。RxSwift 中关键点就是如何把普通的数据或者事件变成可观察的,这样当某些数据或事件有变化的时候就会通知它的订阅者。
RxSwift 中提供很多种创建 Observable 创建方法。比如:From、never、empty 和 create 等
,更多创建方法。
订阅者可以收到 3 个事件,onNext、onError 和 onCompleted
,每个 Observable 都应该至少有一个 onError 或 onCompleted 事件,onNext 表示它传给下一个接收者时的数据流。
在RxSwift中我们把它理解为:观察者序列(就是一系列可以被监听,观察的事件等,当你订阅了这些序列,你就可以在闭包中监听到对应的事件)
序列监听有三个步骤:1.创建序列,2.订阅序列,3.销毁序列
。当创建序列,并订阅了序列后,只要某个事件发送了序列消息,就可以在订阅的闭包里面监听到。下面我们一个小的实例来加深理解:
//1:创建序列
//利用函数式编程思想,在create()构造函数中传入一个闭包,这个闭包会被类对象保存起来,后续每个时间,事件触发的时候会回调这个传入的闭包,这样就像连接了一个链条一样,顺着链条就可找到需要调用的闭包。
let ob = Observable<Any>.create { (observer) -> Disposable in
// 3:发送信号
obserber.onNext([1,2,3,4])
obserber.onCompleted()
// obserber.onError(NSError.init(domain: "error!", code: 10087, userInfo: nil))
return Disposables.create()
//2:订阅信息
//当我们订阅了Observable的消息后,只要Observable的事件触发,都会通过OnNext这个闭包告诉我们。
let _ = ob.subscribe(onNext: { (text) in
print("订阅到:\(text)") //这里会监听到订阅的Observable消息
}, onError: { (error) in
print("error: \(error)") //当发生错误时,会回调这里
}, onCompleted: { // 当所有序列执行完毕时,会回调这里。
print("完成")
}) {
print("销毁")
}
默认的情况下,某些可观察对象是在订阅者订阅时的那个线程中执行。
- 对比传统UIButton响应事件写法和RxSwift中函数响应式写法的区别
- 传统写法
UI代码和逻辑是分开的,为了监听一个按钮的响应事件,我们需要在另外一处地方实现。这样可读性不好,代码繁琐。
button = UIButton()
button.addTarget(self, action: #selector(text), for: .touchUpInside)
@objc func text() {
print("Button clicked!")
}
- Rxswift写法
Rxswift的实现就简单多了,而且目标非常明确,就是三部曲:
1 创建序列 2 订阅响应消息 3 析构销毁
当你订阅了响应消息后,只要序列发生了变化,订阅的消息总会触发,如下面的代码,当你订阅了按钮的点击事件后,每次点击按钮,订阅的消息subscibe就会收到一次。
self.button.rx.tap //序列,这里默认的序列是默认是.onTouchUpInside事件
.subscribe(onNext: { () in //订阅
print("Button clicked!")
}, onError: { (error) in // 当Rxswift的事件链走不通,会回调这个onError,通知错误
print("错误信息")
}, onCompleted: { // 当Rxswift订阅的所有事件链走完了,会回调这个onCompleted,告知执行完毕,这个和onError是对立互斥的,两者只会发生一个。
print("订阅完成")
})
.disposed(by: DisposeBag()) //销毁