RXSwift学习之路--持续更新

一、RXSwift 介绍

1.1 什么是RX

  • Rx 是 ReactiveX 的缩写,简单来说就是基于异步 Event(事件)序列的响应式编程。
  • Rx 可以简化异步编程方法,并提供更优雅的数据绑定。让我们可以时刻响应新的数据同时顺序地处理它们。

1.2 Rx 库

  • Rx 本身可以说是一种跨平台的标准,它有自己的社区论坛,不管是 web 还是移动开发,都能用 Rx 的思维和方法来完成你的工作。
  • 作为一种跨平台标准,目前已经有许多基于不同开发语言的 Rx 的库。除了我后面会着重介绍的 RxSwift 之外,还有 RxJava, RxJS, RxKotlin, Rx.NET...等等。
  • 这些 Rx 库虽然用的语言不同,但它们之间其实都是相通的,都有相同的 API。所以说如果以后你使用别的语言做其他的方面的开发,同样是可以使用相同的思维甚至相同的方法接口(除了语言不同)来编程。
  • 它的主页:http://reactivex.io

1.3 为什么要使用Rx

  • 复合 - Rx 就是复合的代名词
  • 复用 - 因为它易复合
  • 清晰 - 因为声明都是不可变更的
  • 易用 - 因为它抽象的了异步编程,使我们统一了代码风格
  • 稳定 - 因为 Rx 是完全通过单元测试的

二、RxSwift 介绍

2.1 RxSwift 的作用

  • 在编写代码时我们经常会需要检测某些值的变化(比如:textFiled 输入值的变化、数据请求完成或失败的变化),然后进行相应的处理。
  • 过去针对不同的情况,我们需要采用不同的事件传递方法去处理,比如:delegate、notification、target-action、KVO 等等。
  • 而 RectiveX 机制(由 RxSwift 实现)的出现,让程序里的事件传递响应方法做到统一。将之前那些常用的事件传递方法(比如:delegate、notification、target-action 等等),全部替换成 Rx 的“信号链”方式。

2.2 如果我们平时使用的是 MVVM 开发模式的话,通过 RxSwift 可以获得更加方便的数据绑定的方法,使得 MVVM 开发更加如虎添翼。

2.3 RxSwift 与 RxCocoa

  • 前面配置的时候,我们会在 Swift 项目中引入 RxSwift、RxCocoa 这两个库,他们的作用分别是:
  • RxSwift:它只是基于 Swift 语言的 Rx 标准实现接口库,所以 RxSwift 里不包含任何 Cocoa 或者 UI 方面的类。
  • RxCocoa:是基于 RxSwift 针对于 iOS 开发的一个库,它通过 Extension 的方法给原生的比如 UI 控件添加了 Rx 的特性,使得我们更容易订阅和响应这些控件的事件。

三、Observable 介绍

  • Observable 作为 Rx 的根基,我们首先对它要有一些基本的了解。

3.1 Observable<T>

  • Observable<T> 这个类就是 Rx 框架的基础,我们可以称它为可观察序列。它的作用就是可以异步地产生一系列的 Event(事件),即一个 Observable<T> 对象会随着时间推移不定期地发出 event(element : T) 这样一个东西。
  • 而且这些 Event 还可以携带数据,它的泛型 <T> 就是用来指定这个 Event 携带的数据的类型。
  • 有了可观察序列,我们还需要有一个 Observer(订阅者)来订阅它,这样这个订阅者才能收到 Observable<T> 不时发出的 Event。

3.2 Event

  • Event 就是一个枚举,也就是说一个 Observable 是可以发出 3 种不同类型的 Event 事件:

next:next 事件就是那个可以携带数据 <T> 的事件,可以说它就是一个“最正常”的事件。
error:error 事件表示一个错误,它可以携带具体的错误内容,一旦 Observable 发出了 error event,则这个 Observable 就等于终止了,以后它再也不会发出 event 事件了。
completed:completed 事件表示 Observable 发出的事件正常地结束了,跟 error 一样,一旦 Observable 发出了 completed event,则这个 Observable 就等于终止了,以后它再也不会发出 event 事件了。

3.3 Observable 与 Sequence比较

  • 为更好地理解,我们可以把每一个 Observable 的实例想象成于一个 Swift 中的 Sequence:
  • 即一个 Observable(ObservableType)相当于一个序列 Sequence(SequenceType)。
  • ObservableType.subscribe(_:) 方法其实就相当于 SequenceType.generate()
  • 但它们之间还是有许多区别的:
  • Swift 中的 SequenceType 是同步的循环,而 Observable 是异步的。
  • Observable 对象会在有任何 Event 时候,自动将 Event 作为一个参数通过 ObservableType.subscribe(_:) 发出,并不需要使用 next 方法。

四、创建 Observable 序列

4.1 just() 方法

  • 该方法通过传入一个默认值来初始化。
  • 下面样例我们显式地标注出了 observable 的类型为 Observable<Int>,即指定了这个 Observable 所发出的事件携带的数据类型必须是 Int 类型的。
let observable = Observable<Int>.just(5)

4.2 of() 方法

  • 该方法可以接受可变数量的参数(必需要是同类型的)
  • 下面样例中我没有显式地声明出 Observable 的泛型类型,Swift 也会自动推断类型。
let observable = Observable.of("A", "B", "C")

4.3 from() 方法

  • 该方法需要一个数组参数
  • 下面样例中数据里的元素就会被当做这个 Observable 所发出 event 携带的数据内容,最终效果同上面饿 of() 样例是一样的。
let observable = Observable.from(["A", "B", "C"])

4.4 empty() 方法

  • 该方法无需参数
  • 该方法创建一个空内容的 Observable 序列。
let observable = Observable<Int>.empty()

4.5 never() 方法

  • 该方法无需参数
  • 该方法创建一个永远不会发出 Event(也不会终止)的 Observable 序列。
let observable = Observable<Int>.never()

4.6 error() 方法

  • 该方法需要一个Error对象
  • 该方法创建一个不做任何操作,而是直接发送一个错误的 Observable 序列。
enum MyError: Error {
    case A
    case B
}
let observable = Observable<Int>.error(MyError.A)

4.7 range() 方法

  • 该方法通过指定起始和结束数值,创建一个以这个范围内所有值作为初始值的 Observable 序列。
  • 下面样例中,两种方法创建的 Observable 序列都是一样的。
//使用range()
let observable = Observable.range(start: 1, count: 5)
 
//使用of()
let observable = Observable.of(1, 2, 3 ,4 ,5)

4.8 repeatElement() 方法

  • 该方法需要整数
  • 该方法创建一个可以无限发出给定元素的 Event 的 Observable 序列(永不终止)。
let observable = Observable.repeatElement(1)

五、Subjects 介绍

  • 即是订阅者也是Observable(可观察序列)
  • Observable 在运行时能动态地“获得”或者说“产生”出一个新的数据,再通过 Event 发送出去。比如:订阅一个输入框的输入内容,当用户每输入一个字后,这个输入框关联的 Observable 就会发出一个带有输入内容的 Event,通知给所有订阅者。

5.1 Subjects 基本介绍

  • Subjects 既是订阅者,也是 Observable:
  • 说它是订阅者,是因为它能够动态地接收新的值。
  • 说它又是一个 Observable,是因为当 Subjects 有了新的值之后,就会通过 Event 将新值发出给他的所有订阅者。

5.2 Subjects对象

    1. PublishRelay: PublishRelay 是对PublishSubject的包装
    1. BehaviorRelay: BehaviorRelay是对BehaviorSubject的包装
    1. ReplaySubject
    1. Variable
  • 首先他们都是 Observable,他们的订阅者都能收到他们发出的新的 Event。
    直到 Subject 发出 .complete 或者 .error 的 Event 后,该 Subject 便终结了,同时它也就不会再发出 .next 事件。
  • 对于那些在 Subject 终结后再订阅他的订阅者,也能收到 subject 发出的一条 .complete 或 .error 的 event,告诉这个新的订阅者它已经终结了。
  • 他们之间最大的区别只是在于:当一个新的订阅者刚订阅它的时候,能不能收到 Subject 以前发出过的旧 Event,如果能的话又能收到多少个。

5.3 Subject 常用的几个方法:

  • onNext(:):是 on(.next(:)) 的简便写法。该方法相当于 subject 接收到一个 .next 事件。
  • onError(:):是 on(.error(:)) 的简便写法。该方法相当于 subject 接收到一个 .error 事件。
  • onCompleted():是 on(.completed) 的简便写法。该方法相当于 subject 接收到一个 .completed 事件。

5.4 PublishRelay

  • PublishRelay 是最普通的 Subject,它不需要初始值就能创建。
  • PublishRelay 的订阅者从他们开始订阅的时间点起,可以收到订阅后 Subject 发出的新 Event,而不会收到他们在订阅前已发出的 Event。

5.5 BehaviorSubject

  • BehaviorSubject 需要通过一个默认初始值来创建。
  • 当一个订阅者来订阅它的时候,这个订阅者会立即收到 BehaviorSubjects 上一个发出的 event。之后就跟正常的情况一样,它也会接收到 BehaviorSubject 之后发出的新的 event。

5.6 ReplaySubject

  • ReplaySubject 在创建时候需要设置一个 bufferSize,表示它对于它发送过的 event 的缓存个数。
  • 比如一个 ReplaySubject 的 bufferSize 设置为 2,它发出了 3 个 .next 的 event,那么它会将后两个(最近的两个)event 给缓存起来。此时如果有一个 subscriber 订阅了这个 ReplaySubject,那么这个 subscriber 就会立即收到前面缓存的两个 .next 的 event。
  • 如果一个 subscriber 订阅已经结束的 ReplaySubject,除了会收到缓存的 .next 的 event 外,还会收到那个终结的 .error 或者 .complete 的 event。

5.7 Variable

  • Variable 其实就是对 BehaviorSubject 的封装,所以它也必须要通过一个默认的初始值进行创建。
  • Variable 具有 BehaviorSubject 的功能,能够向它的订阅者发出上一个 event 以及之后新创建的 event。
  • 不同的是,Variable 还把会把当前发出的值保存为自己的状态。同时它会在销毁时自动发送 .complete 的 event,不需要也不能手动给 Variables 发送 completed 或者 error 事件来结束它。
  • 简单地说就是 Variable 有一个 value 属性,我们改变这个 value 属性的值就相当于调用一般 Subjects 的 onNext() 方法,而这个最新的 onNext() 的值就被保存在 value 属性里了,直到我们再次修改它。

5.8 BehaviorRelay是对BehaviorSubject的包装,其事件也不太一样

  • BehaviorRelay 是作为 Variable 的替代者出现的。它的本质其实也是对 BehaviorSubject 的封装,所以它也必须要通过一个默认的初始值进行创建。
  • BehaviorRelay 具有 BehaviorSubject 的功能,能够向它的订阅者发出上一个 event 以及之后新创建的 event。
  • 与 BehaviorSubject 不同的是,不需要也不能手动给 BehaviorReply 发送 completed 或者 error 事件来结束它(BehaviorRelay 会在销毁时也不会自动发送 .complete 的 event)。
  • BehaviorRelay 有一个 value 属性,我们通过这个属性可以获取最新值。而通过它的 accept() 方法可以对值进行修改。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容