RxSwfit 基础概论

RxSwif是ReactiveX的Swift版本,也就是一个函数式响应编程的框架。

函数式响应编程:面向异步数据流编程,关键是对函数和状态的理解。

组成

  • 可观察序列 (Observables aka Sequences)
  • 事件 next\error\completed
  • Observer 观察者

使用

可观察序列 (Observables aka Sequences)

事件 next\error\completed

Observer 观察者

序列Sequence

第一,它的容量可以有限也可无限;
第二,只可以迭代 (iterate) 一次。

protocol Sequence {
associatedtype Iterator: IteratorProtocol
func makeIterator() -> Iterator
}

观察序列的创建

Observable订阅

监听事件的生命周期

Observable的销毁

DisposeBag

AnyObserver、Binder

Subject

  • PublishSubject
  • BehaviorSubject
  • ReplaySubject
  • Variable

Transforming Observables

buffer:

buffer 方法作用是缓冲组合,第一个参数是缓冲时间,第二个参数是缓冲个数,第三个参数是线程。
该方法简单来说就是缓存 Observable 中发出的新元素,当元素达到某个数量,或者经过了特定的时间,它就会将这个元素集合发送出来。

window:

window 操作符和 buffer 十分相似。不过 buffer 是周期性的将缓存的元素集合发送出来,而 window 周期性的将元素集合以 Observable 的形态发送出来。

同时 buffer 要等到元素搜集完毕后,才会发出元素序列。而 window 可以实时发出元素序列

map

该操作符通过传入一个函数闭包把原来的 Observable 序列转变为一个新的 Observable 序列。

flatMap??

map 在做转换的时候容易出现“升维”的情况。即转变之后,从一个序列变成了一个序列的序列。

而 flatMap 操作符会对源 Observable 的每一个元素应用一个转换方法,将他们转换成 Observables。 然后将这些 Observables 的元素合并之后再发送出来。即又将其 “拍扁”(降维)成一个 Observable 序列。

这个操作符是非常有用的。比如当 Observable 的元素拥有其他的 Observable 时,我们可以将所有子 Observables 的元素发送出来。

flatMapLatest

flatMapLatest 与 flatMap 的唯一区别是:flatMapLatest 只会接收最新的 value 事件。

flatMapFirst

flatMapFirst 与 flatMapLatest 正好相反:flatMapFirst 只会接收最初的 value 事件。

concatMap

concatMap 与 flatMap 的唯一区别是:当前一个 Observable 元素发送完毕后,后一个Observable 才可以开始发出元素。或者说等待前一个 Observable 产生完成事件后,才对后一个 Observable 进行订阅。

scan

scan 就是先给一个初始化的数,然后不断的拿前一个结果和最新的值进行处理操作。

groupBy

groupBy 操作符将源 Observable 分解为多个子 Observable,然后将这些子 Observable 发送出来。

也就是说该操作符会将元素通过某个键进行分组,然后将分组后的元素序列以 Observable 的形态发送出来。

过滤操作符(Filtering Observables)

filter

规则过滤

distinctUntilChanged

重复事件过滤

single

限制发送一次事件或满足条件的第一个事件

elementAt

只处理特定位置的事件

ignoreElements

忽略所有元素、只发出error或completed

take

只发送前n个事件

takeLast

只发送后n个事件

skip

忽略前n个事件

Sample

Sample 除了订阅源Observable 外,还可以监视另外一个 Observable, 即 notifier 。
每当收到 notifier 事件,就会从源序列取一个最新的事件并发送。而如果两次 notifier 事件之间没有源序列的事件,则不发送值。

debounce

节流,限制高频产生数据,要求元素和下个元素的间隔小于指定的时间间隔

条件和布尔操作符(Conditional and Boolean Operators)

amb

当传入多个 Observables 到 amb 操作符时,它将取第一个发出元素或产生事件的 Observable,然后只发出它的元素。并忽略掉其他的 Observables

takeWhile

该方法依次判断 Observable 序列的每一个值是否满足给定的条件。 当第一个不满足条件的值出现时,它便自动完成。

takeUntil

同时监视notifier。

如果 notifier 发出值或 complete 通知,那么源 Observable 便自动完成,停止发送事件。

skipWhile

跳过前面所有满足条件的事件

skipUntil

同时监听notifier

源 Observable 序列事件默认会一直跳过,直到 notifier 发出值或 complete 通知。

结合操作(Combining Observables)

startWith

发送事件消息之前,先发出预先插入的消息

merge

该方法可以将多个(两个或两个以上的)Observable 序列合并成一个 Observable序列

zip

将两个或两个以上Observable序列压缩成一个Observable序列,并且等到每个Observable事件一一凑齐后再合并

combineLastest

将多个Observable合并,每当任意Observable有新事件发出,它会将每个 Observable 序列的最新的一个事件元素进行合并。

withLatesFrom

将两个Observable序列合并,每当 self 队列发射一个元素时,便从第二个序列中取出最新的一个值。

switchLatest

switchLatest 有点像其他语言的switch 方法,可以对事件流进行转换。
比如本来监听的 subject1,我可以通过更改 variable 里面的 value 更换事件源。变成监听 subject2。

算数、以及聚合操作(Mathematical and Aggregate Operators)

toArray

把序列转成一个数组,并作为一个单一的事件发送,然后结束

reduce

接收一个初始值和一个操作符号,将给定的初始值,与序列里的每个值进行累计运算。得到一个最终结果,并将其作为单个值发送出去。

concat

顺序化

把多个 Observable 序列合并(串联)为一个 Observable 序列。

并且只有当前面一个 Observable 序列发出了 completed 事件,才会开始发送下一个 Observable 序列事件。

连接操作(Connectable Observable Operators)

可连接的序列(Connectable Observable):

(1)可连接的序列和一般序列不同在于:有订阅时不会立刻开始发送事件消息,只有当调用 connect()之后才会开始发送值。

(2)可连接的序列可以让所有的订阅者订阅后,才开始发出事件消息,从而保证我们想要的所有订阅者都能接收到事件消息。

publish

publish 方法会将一个正常的序列转换成一个可连接的序列。同时该序列不会立刻发送事件,只有在调用 connect 之后才会开始。

replay

replay 与 publish 不同在于:新的订阅者还能接收到订阅之前的事件消息(数量由设置的 bufferSize 决定)。

multicast

同样是将一个正常的序列转换成一个可连接的序列。
同时还可以传入一个 Subject,每当序列发送事件时都会触发这个 Subject 的发送。

refCount

将可被连接的 Observable 转换为普通 Observable

可以自动连接和断开可连接的 Observable。当第一个观察者对可连接的Observable 订阅时,那么底层的 Observable 将被自动连接。当最后一个观察者离开时,那么底层的 Observable 将被自动断开连接。

share(relay:)

使得观察者共享源 Observable,并且缓存最新的 n 个元素,将这些元素直接发送给新的观察者。
简单来说 shareReplay 就是 replay 和 refCount 的组合。

其他一些实用的操作符(Observable Utility Operators)

delay

延迟发送Observable的元素

delaySubscription

延迟订阅

materialize

事件转换成元素

dematerialize

元素还原成事件

timeout

设置超时时间

using

创建 Observable 时,同时会创建一个可被清除的资源,一旦 Observable终止了,那么这个资源就会被清除掉了。

错误处理操作(Error Handling Operators)

catchErrorJustReturn

当遇到 error 事件的时候,就返回指定的值,然后结束。

catchError

捕获 error,并对其进行处理。

同时还能返回另一个 Observable 序列进行订阅(切换到新的序列)。

retry

使用该方法当遇到错误的时候,会重新订阅该序列。

调试操作

debug

将 debug 调试操作符添加到一个链式步骤当中,这样系统就能将所有的订阅者、事件、和处理等详细信息打印出来,方便我们开发调试。

RxSwift.Resources.total

将 RxSwift.Resources.total 打印出来,我们可以查看当前 RxSwift 申请的所有资源数量。这个在检查内存泄露的时候非常有用。

特征序列(Traits)

Observable 是能够用于任何上下文环境的通用序列。

而 Traits 可以帮助我们更准确的描述序列。同时它们还为我们提供上下文含义、语法糖,让我们能够用更加优雅的方式书写代码。

Single

  • 发出一个元素,或一个 error 事件
  • 不会共享状态变化
  • SingleEvent
1
2
3
4
public enum SingleEvent<Element> {
case success(Element)
case error(Swift.Error)
}

asSingle()

调用 Observable 序列的.asSingle()方法,将它转换为 Single。

Completable

  • 不会发出任何元素
  • 只会发出一个 completed 事件或者一个 error 事件
  • 不会共享状态变化

CompletableEvent

1
2
3
4
public enum CompletableEvent {
case error(Swift.Error)
case completed
}

Maybe

  • 发出一个元素、或者一个 completed 事件、或者一个 error 事件
  • 不会共享状态变化
  • 适合那种可能需要发出一个元素,又可能不需要发出的情况。

MaybeEvent

1
2
3
4
5
public enum MaybeEvent<Element> {
case success(Element)
case error(Swift.Error)
case completed
}

asMaybe()

调用 Observable 序列的 .asMaybe()方法,将它转换为 Maybe。

Driver

  • 不会产生 error 事件
  • 一定在主线程监听(MainScheduler)
  • 共享状态变化(shareReplayLatestWhileConnected)

ControlProperty

  • 专门用来描述 UI 控件属性,拥有该类型的属性都是被观察者(Observable)
  • 不会产生 error 事件
  • 一定在 MainScheduler 订阅(主线程订阅)
  • 一定在 MainScheduler 监听(主线程监听)
  • 共享状态变化

调度器(Schedulers)

调度器(Schedulers)是 RxSwift 实现多线程的核心模块,它主要用于控制任务在哪个线程或队列运行。

  • CurrentThreadScheduler:表示当前线程 Scheduler。(默认使用这个)
  • MainScheduler:表示主线程。如果我们需要执行一些和 UI 相关的任务,就需要切换到该 Scheduler运行。
  • SerialDispatchQueueScheduler:封装了 GCD 的串行队列。如果我们需要执行一些串行任务,可以切换到这个 Scheduler 运行。
  • ConcurrentDispatchQueueScheduler:封装了 GCD 的并行队列。如果我们需要执行一些并发任务,可以切换到这个 Scheduler 运行。
  • OperationQueueScheduler:封装了 NSOperationQueue。
  Total:    No.