响应式编程
operation DataBind
Observeable<T> ---------> Observer<Bool> ------------> Observer<Bool>
(可观察者) 观察者 Disposable(管理订阅/绑定的声明周期)
1. Observable<T>
-
Observable<T> 这个类就是 **Rx 框架的基础,我们可以称它为可观察序列。它的作用就是可以异步地产生一系列的 Event(事件),即一个 Observable<T> **对象会随着时间推移不定期地发出 **event(element : T) **这样一个东西。
-
而且这些 **Event **还可以携带数据,它的泛型 <T> 就是用来指定这个 **Event **携带的数据的类型。
-
有了可观察序列,我们还需要有一个 Observer(订阅者)来订阅它,这样这个订阅者才能收到 Observable<T> 不时发出的 Event
需要将Foundation中的数据转换成Observable. 有将近10多种转换方式.
2. Event
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
}
一个Observable 可以发出3中不同类型的Event 事件.
3. Observable 的创建
大约有13中方法可以进行创建, 对应的observable实例对象有着不同的作用.
4. Observable 的订阅
第一种用法
- 直接使用 **subscribe() **订阅了一个 **Observable **对象, 回调参数是发出的event事件.
let observable = Observable.of("A", "B", "C")
observable.subscribe { event in
print(event)
}
打印结果:
next(A)
next(B)
next(C)
completed
event 是按顺序通过.next 事件发送出来的.
- 如果要获得事件中的数据,通过event.element得到
let observable = Observable.of("A", "B", "C")
observable.subscribe { event in
print(event.element)
}
打印结果:
Optional("A")
Optional("B")
Optional("C")
nil
第二种方法
另一个subsciibe方法,把event分类
let observable = Observable.of("A", "B", "C")
observable.subscribe(onNext: { element in
print(element)
}, onError: { error in
print(error)
}, onCompleted: {
print("completed")
}, onDisposed: {
print("disposed")
})
简化写法,只处理onNext,不管其它情况
let observable = Observable.of("A", "B", "C")
observable.subscribe(onNext: { element in
print(element)
})
监听事件的生命周期
使用doOn实现,
- **do(onNext:) **方法就是在 **subscribe(onNext:) **前调用
- 而 do(onCompleted:) 方法则会在 **subscribe(onCompleted:) **前面调用。
let observable = Observable.of("A", "B", "C")
observable
.do(onNext: { element in
print("Intercepted Next:", element)
}, onError: { error in
print("Intercepted Error:", error)
}, onCompleted: {
print("Intercepted Completed")
}, onDispose: {
print("Intercepted Disposed")
})
.subscribe(onNext: { element in
print(element)
}, onError: { error in
print(error)
}, onCompleted: {
print("completed")
}, onDisposed: {
print("disposed")
})
Observable 的销毁 (Dispose)
Observable 创建之后,等到被订阅之后,才会结果从而发出event.
1. 使用dispose
- dispose方法,可以手动取消一个订阅;
- 当一个订阅被dispose,之后的Observable在发出event,被dispose的订阅不会接受到消息了.
let observable = Observable.of("A", "B", "C")
//使用subscription常量存储这个订阅方法
let subscription = observable.subscribe { event in
print(event)
}
//调用这个订阅的dispose()方法
subscription.dispose()
2. 使用DisposeBag
- 我们可以把一个 **DisposeBag **对象看成一个垃圾袋,把用过的订阅行为都放进去。
- 而这个 **DisposeBag **就会在自己快要 **dealloc **的时候,对它里面的所有订阅行为都调用 **dispose() **方法。
感觉类似于autorelease.
let disposeBag = DisposeBag()
//第1个Observable,及其订阅
let observable1 = Observable.of("A", "B", "C")
observable1.subscribe { event in
print(event)
}.disposed(by: disposeBag)
//第2个Observable,及其订阅
let observable2 = Observable.of(1, 2, 3)
observable2.subscribe { event in
print(event)
}.disposed(by: disposeBag)
5. 特征序列
我们都知道 Swift 是一个强类型语言,而强类型语言相对于弱类型语言的一个优点是更加严谨。我们可以通过类型来判断出,实例有哪些特征。同样的在 RxSwift 里面 Observable
也存在一些特征序列,这些特征序列可以帮助我们更准确的描述序列。并且它们还可以给我们提供语法糖,让我们能够用更加优雅的方式书写代码,他们分别是:
- Single
- Completable
- Maybe
- Signal
- ControlEvent
5.1 Single
observable的另一个版本, 只发出一个元素或者一个error 事件. 常见于HTTP 请求, 适用于任何只有一个元素的序列.
5.2 Completable
observable的另一个版本 .
- 发出零个元素
- 发出一个completed 事件或一个error事件
5.3 Maybe
- 介于SIngle 和 Completable
- 发出一个元素或一个completable事件或一个error
5.4 Driver
主要目的是简化UI 层的代码; 适用于以下特征的序列
-
不会产生error 事件
-
一定在MAinScheduler 鉴定(主线程监听)
-
共享附加作用
例子: 一个TeXFiled的输入,发起网络请求,将结果绑定到一个label和一个tableview进行显示;
-
如果网络请求失败,则会取消所有绑定,无法发起新的网络请求.
-
如果网络请求在后台返回,则刷新UI也在后台,会出现异常崩溃
-
绑定到两个UI上, 每输入一个文字,则会为这两个UI元素发起两个网络请求.
使用Driver 就是为了避免以上情况的发生.
在讲一个序列转换为Driver之后, 又有了一个新的观察者,这个观察者会得到Driver的上一个元素.
或者说 新的订阅者总会得到一个最新值, 这对于UI来说没什么问题,但是对于事件就会有问题. 我们只想要最新的事件,而不是旧事件.
这一点和Flutter中的RxDart 类似了, 毕竟是一个思想.
5.5 Signal
signal 和Driver 类似, 但有新的订阅者,并不会把上次的点击事件回访给这个新观察者,只会将订阅后产生的订阅事件,发布给新的观察者.
总结: 状态序列使用Driver 事件序列使用Signal.
5.6 ControlEvent
专门用于描述UI控件产生的事件
-
不会产生error事件
-
一定在MainSchedule订阅 (主线程定于)
-
一定在MainSchedule 监听(主线程监听)
6. Observer(观察者)
Observer 的作用就是监听事件, 对事件作出响应.
任何对响应事件的行为都是观察者.
创建观察者
- 在subscribe中创建
let observable = Observable.of("A", "B", "C")
observable.subscribe(onNext: { element in
print(element)
}, onError: { error in
print(error)
}, onCompleted: {
print("completed")
})
上面闭包中的处理行为,就是一个观察者.
- 在bind方法中创建
7.Observable & Observer 即是可监听序列也是观察者
7.1 AsyncSubject
特点: 在Obserable 产生事件完成后,发出最后一个元素(仅仅只有最后一个元素).
需要确定Obserable 产生完事件,否则会不执行.
let asyncSubject = AsyncSubject<String>()
asyncSubject.subscribe { print( "当前为: ", $0) }
.disposed(by: disposeBag)
asyncSubject.onNext("哈哈哈")
asyncSubject.onCompleted()
如果没有这行的代码
asyncSubject.onCompleted()
事件不会执行.
7.2 PublishSubject
作为Observer,将对观察者发送订阅后产生的元素, 订阅前发出的元素 将不会发送给观察者.
let publicSubject = PublishSubject<String>()
publicSubject.subscribe { print("1 Event", $0)}
.disposed(by: disposeBag)
publicSubject.onNext("1111")
publicSubject.onNext("2222")
publicSubject.subscribe { print("2 Event", $0)}
.disposed(by: disposeBag)
publicSubject.onNext("333")
publicSubject.onNext("4444")
这个publicSubject有两个订阅者, 第二个订阅之后,产生了事件, 这两个订阅者同时执行了对应的方法. 但是第二个订阅者没有执行没订阅之前的方法.
1 Event next(1111)
1 Event next(2222)
1 Event next(333)
2 Event next(333)
1 Event next(4444)
2 Event next(4444)
7.3 ReplaySubject
对观察者发送全部的元素, 无论观察者何时进行订阅的.
这里存在多个版本的 ReplaySubject,有的只会将最新的 n 个元素发送给观察者,有的只会将限制时间段内最新的元素发送给观察者。
如果把 ReplaySubject 当作观察者来使用,注意不要在多个线程调用 onNext
, onError
或 onCompleted
。这样会导致无序调用,将造成意想不到的结果。
注释: 上面的那句话没有进行对应的代码进行验证. 不是很理解.
//bufferSize 表示 在有新的订阅者之后, 会将之前的几个时间发送给新订阅者
let replaySubject = ReplaySubject<String>.create(bufferSize: 1)
replaySubject.subscribe { print("1 Event", $0)}
.disposed(by: disposeBag)
replaySubject.onNext("11111")
replaySubject.onNext("22222")
replaySubject.subscribe { print("2 Event", $0)}
.disposed(by: disposeBag)
replaySubject.onNext("33333")
replaySubject.onNext("44444")
打印如下:
1 Event next(11111)
1 Event next(22222)
2 Event next(22222)
1 Event next(33333)
2 Event next(33333)
1 Event next(44444)
2 Event next(44444)
可以看到,2 Event next(22222) 这个事件发生了两次. 因为bu
7.4 BehaviorSubject
7.5 ControlProperty
专门用于描述UI控件属性的,具有以下特征
-
不会产生error 事件
-
一定在MainScheduler 订阅 (在主线程订阅)
-
一定在MainScheduler 监听 (在主线程监听)
-
共享附加作用
好了,谢谢大家看完之前分享的RxSwift 核心东西对于有些小伙伴感觉很难,所以分享一些基础的学习知识,希望对你有所帮助,感谢家人们的支持!
网友评论