RxSwift学习教程之类型对象Subject详解

2020-01-08 23:39:27于海丽

前言

在上一篇文章我们介绍了 Observable 的基本概念和使用情形。但是大多数情形下,我们需要在应用运行时添加数据到 Observable 中并将其发送给订阅者。在这种需求场景下,我们就不得不使用 RxSwift 中另一种类型对象了 - Subject 。

在应用中 Subject 实际上同时扮演了两个不同的角色:既是可观察对象同时也是观察者。这意味着 Subject 实例对象既可以接收事件也可以发送事件。例如,Subject 实例对象可以接收 next 事件信息,然后再将其发送给它自己的订阅者。示例代码:


let subject = PublishSubject<String>()

let subscriptionOne = subject
       .subscribe(onNext: { string in
        print(string)
       })

subject.on(.next("1"))

/* 打印结果:
1
*/

上面代码中使用的是 PublishSubject 类型的示例,而 RxSwift 中总共也四种类型的 Subject:

PublishSubject:初始化时并不包含数据,并且只会给订阅者发送后续数据。 BehaviorSubject:创建时需要包含初始数据,并且会给订阅者发送后续数据和最近的一次数据。 ReplaySubject:创建时需要指定对象缓存区容量,该容量表示会给订阅者重新发送订阅前数据的大小。 Variable:BehaviorSubject 对象的封装类型。它会将当前数据保存为状态并且只会给订阅者重新发送最近或者初始值。

下面将详细介绍这四种类型对象的概念以及它们的区别和使用情况。

PublishSubject

如果你仅仅是想让订阅者获取被观察者在生命周期内若产生的数据的话,那么你完全可以选用 PublishSubject 。而且 PublishSubject 对象的行为符合正常的预期,它只会给订阅者发送其订阅开始之后的数据。

例如,下图的最上面的时间线表示被观察者所发送的事件,而下面两个则分别代表不同的观察者。可以看到下面两个观察者都只会接收到订阅后所发送的事件而无法获知之前的情形。

rxswift,rx,subject,教程

对应的代码为:


let subject = PublishSubject<String>()

let subscriptionOne = subject
       .subscribe(onNext: { event in
        print("1) ( event.element ?? event)" )
       })

subject.on(.next("1")) 

let subscriptionTwo = subject
       .subscribe(onNext: { event in
        print("2) (event.element ?? event)")
       })
 
subject.on(.next("2")) 

subject.on(.next("3")) 

/* 打印结果
1) 1
1) 2
2) 2
1) 3
2) 3
*/

如果此时我们取消 subscriptionOne 的订阅并发送新数据的话,那么结果为:


subscriptionOne.dispose()
subject.on(.next("4")) 

 /* 打印结果
 2) 4
 */