学科

Subject是一个代理,即Subject即是Observable又是Observer。

Subject可以作为一个Observer订阅一个或多个Observable,又可以作为一个Observable被其他的Observer订阅。

它可以传递/转发做为观察者收到的值,也可以主动发射值。

Subject在RxSwift中的实现有多种。

  • PublishSubject对应ReactiveX中的PublishSubject
  • ReplaySubject对应ReactiveX中的ReplaySubject
  • BehaviorSubject对应ReactiveX中的BehaviorSubject
  • 变量

发布主题

代理

我们先以PublishSubject解释主题为一个代理的含义。

 让publishSubject = PublishSubject () 
发布主题
.subscribe {事件在
print(“事件:\(事件)。”)
}
publishSubject.onNext(1)
publishSubject.onNext(2)
publishSubject.onNext(3)
publishSubject.onCompleted()

Subject做为Observable提供了订阅等方法。在订阅之后我们调用了onNext方法,向Observer发射了1、2、3,完成。打印结果和我们的预期一样。

 事件:next(1)。 
事件:next(2)。
事件:next(3)。
活动:完成。

我们可以调用Subject的系列方法主动发送值给Observable。

注意在这里如果我们在订阅之前调用了on Next方法,观察者将不会收到发送的值,这一点涉及到Hot Observable的概念,我们放到后面讨论这个问题。

Subject可以作为代理转发订阅到的结果。

 让publishSubject = PublishSubject () 

发布主题
.subscribe {事件在
print(“事件:\(事件)。”)
}
让intSequence = Observable
.create {(观察者)->一次性
viewer.onNext(1)
viewer.onNext(2)
viewer.onNext(3)
rator.onCompleted()
返回Disposables.create()
}
intSequence
.subscribe(publishSubject)

publishSubject订阅了intSequence,将结果转发给了Observer。

打印结果和我们预期一样。

 事件:next(1)。 
事件:next(2)。
事件:next(3)。
事件:完成。

特色

在RxSwift中,PublishSubject可能不会在初始化后立即发送数据,这根本上我们什么时候调用在方法上。

和Observable一样,在调用onError或onCompleted都标志着整个数据流的结束。

需要注意的是,观察员订阅PublishSubject时不会收到订阅之前PublishSubject的值。

 让publishSubject = PublishSubject () 
publishSubject.onNext(0)
发布主题
.subscribe {事件在
print(“事件:\(事件)。”)
}
publishSubject.onNext(1)
publishSubject.onNext(2)
publishSubject.onNext(3)
publishSubject.onCompleted()

上述代码打印的结果为:

 事件:next(1)。 
事件:next(2)。
事件:next(3)。
事件:完成。

观察者无法收到0这个值。

重播主题

ReplaySubject和PublishSubjec t的不同是Observer有可能收到订阅之前的值

ReplaySubject具有预设(replay)的功能,replay的个数可以通过参数指定。我们可以将其理解成缓存的效果。

ReplaySubject有2个工厂方法。

 公共类ReplaySubject  { 
公共静态函数create(bufferSize:Int)-> ReplaySubject
公共静态函数createUnbounded()-> ReplaySubject
}

让replaySubject = ReplaySubject .create(bufferSize:3)
replaySubject.onNext(1)
replaySubject.onNext(2)
replaySubject.onNext(3)
replaySubject.onNext(4)
replaySubject.onCompleted()
replaySubject
.subscribe {(event)in
打印(事件)
}

通过create(bufferSize:Int)可以指定需要缓存最新值(不考虑错误和完成)的个数。上述代码我们缓存了三个值。

 事件:next(2)。 
事件:next(3)。
事件:next(4)。
事件:完成。

当我们需要缓存所有值时,可以调用createUnbounded方法。

提示:ReplaySubject .create(bufferSize:0)就等于PublishSubject ()。

行为主体

BehaviorSubject或ReplaySubject具有缓存的能力,但略有不同。

  • 缓存一个最新值 ,类似ReplaySubject.create(bufferSize:1)
  • 需要提供数值
  • let behaviorSubject = BehaviorSubject(值:1)
  • 让replaySubject = ReplaySubject.create(bufferSize:3)
  • replaySubject.onNext(1)

此时behaviorSubject和replaySubject的表现是完全一样的。

  let behaviorSubject = BehaviorSubject (值:1) 
行为主体
.subscribe {(event)in
print(“事件:\(事件)。”)
}

打印结果为:

 事件:next(1)。 

使用BehaviorSubject有一点好处,我们可以确定当Observer订阅时,至少可以收到最新的一个值。

变量

Variable和BehaviorSubject又很相似,Variable是BehaviorSubject的一个封装,同样也是缓存了最新值提供值的能力。但是Variable在系列方法上没有,只提供了value属性。

直接对value进行set等于于调用了onNext方法。

这表明了变量不会发射错误也不会发射完成。

警告:在变量被销毁毁灭时会触发发射完成给观察者。

在订阅Variable时,我们无法直接调用subscription,需要先调用asObservable方法。

 让变量=变量(1) 
variable.asObservable()
.subscribe {(event)in
print(“事件:\(事件)。”)
}
variable.value = 2

上述代码的打印结果为。

 事件:next(1)。 
事件:next(2)。

Variable可以用作储存数据,因为我们可以拥有value的get和set方法。

 让变量=变量(1) 
print(“ Value:\(variable.value)”)
variable.value = 2
print(“ Value:\(variable.value)”)

打印结果为:

 价值:1 
价值:2

这是BehaviorSubject不具备的能力。