當(dāng)我們需要創(chuàng)建一個 Observable的時候,要預(yù)先將要發(fā)送的信號或數(shù)據(jù)準(zhǔn)備好,等到有subscribe時再將數(shù)據(jù)通過 onXX發(fā)出去。
但是,當(dāng)需要Observable 在運行時能動態(tài)地獲取一個新的數(shù)據(jù)時候,再通過onXX發(fā)送給訂閱者,以實現(xiàn)“聯(lián)動”的效果。我們就要用到了Subject。
Subject介紹
SubjectSubject是一個代理,它是特殊的序列,既是Observer,同時又是Observable
Subject分為:PublishSubject、BehaviorSubject、ReplaySubject、AsyncSubject、BehaviorRelay

PublishSubject
-PublishSubject的創(chuàng)建需要定義類型,但不需要初始值。
-PublishSubject的訂閱序列只能接收到subscribe之后的onXX事件,不能接收到subscribe之前的onXX事件。
// 1:初始化序列
let publishSub = PublishSubject<Int>()
//初始化一個PublishSubject 裝著Int類型的序列
// 2:發(fā)送響應(yīng)序列
publishSub.onNext(1)
// 3:訂閱序列
publishSub.subscribe { print("訂閱到了:",$0)}
.disposed(by: disposbag)
// 再次發(fā)送響應(yīng)
publishSub.onNext(2)
publishSub.onNext(3)
訂閱到了: next(2)
訂閱到了: next(3)
BehaviorSubject
-BehaviorSubject 需要的創(chuàng)建需要給定一個初始的默認(rèn)值,第一次subscribe之前如果沒有發(fā)送onXX事件,那么訂閱到的就是這個初始的默認(rèn)值。如果第一次subscribe之前發(fā)送了onXX事件,那么會把初始值覆蓋掉。
-如果subscribe之前發(fā)送多個onXX事件,只會保留臨近的一個; subscribe之后發(fā)送的onXX事件都會執(zhí)行
// 1:創(chuàng)建序列
let behaviorSub = BehaviorSubject.init(value: 100)
// 2:發(fā)送信號
behaviorSub.onNext(1)
behaviorSub.onNext(2)
// 3:訂閱序列
behaviorSub.subscribe{ print("第一次訂閱到了:",$0)}
.disposed(by: disposbag)
// 再次發(fā)送
behaviorSub.onNext(3)
behaviorSub.onNext(4)
// 再次訂閱
behaviorSub.subscribe{ print("第二次訂閱到了:",$0)}
.disposed(by: disposbag)
第一次訂閱到了: next(2)
第一次訂閱到了: next(3)
第一次訂閱到了: next(4)
第二次訂閱到了: next(4)
ReplaySubject
如果初始化設(shè)置bufferSize,那么連續(xù)發(fā)送信號,而subscribe能夠訂閱到的最大數(shù)量為bufferSize
設(shè)置bufferSize
// 1:創(chuàng)建序列
let replaySub = ReplaySubject<Int>.create(bufferSize: 2)
// 2:發(fā)送信號
replaySub.onNext(1)
replaySub.onNext(2)
replaySub.onNext(3)
replaySub.onNext(4)
// 3:訂閱序列
replaySub.subscribe{ print("訂閱到了:",$0)}
.disposed(by: disposbag)
// 再次發(fā)送
replaySub.onNext(7)
replaySub.onNext(8)
replaySub.onNext(9)
訂閱到了: next(3)
訂閱到了: next(4)
訂閱到了: next(7)
訂閱到了: next(8)
訂閱到了: next(9)
createUnbounded,不設(shè)置bufferSize
// 1:創(chuàng)建序列
let replaySub = ReplaySubject<Int>.createUnbounded()
// 2:發(fā)送信號
replaySub.onNext(1)
replaySub.onNext(2)
replaySub.onNext(3)
replaySub.onNext(4)
// 3:訂閱序列
replaySub.subscribe{ print("訂閱到了:",$0)}
.disposed(by: disposbag)
// 再次發(fā)送
replaySub.onNext(7)
replaySub.onNext(8)
replaySub.onNext(9)
訂閱到了: next(1)
訂閱到了: next(2)
訂閱到了: next(3)
訂閱到了: next(4)
訂閱到了: next(7)
訂閱到了: next(8)
訂閱到了: next(9)
AsyncSubject
遇到onError的話,onError之前的onXX發(fā)送全部作廢
// 1:創(chuàng)建序列
let asynSub = AsyncSubject<Int>.init()
// 2:發(fā)送信號
asynSub.onNext(1)
asynSub.onNext(2)
// 3:訂閱序列
asynSub.subscribe{ print("訂閱到了:",$0)}
.disposed(by: disposbag)
// 再次發(fā)送
asynSub.onNext(3)
asynSub.onNext(4)
asynSub.onError(NSError.init(domain: "EpisodeError", code: 10086, userInfo: nil))
asynSub.onCompleted()
訂閱到了: error(Error Domain=EpisodeError Code=10086 "(null)")
BehaviorRelay
BehaviorRelay替代Variable, 無需手寫 on(event)事件,只需給屬性賦值即可獲取事件響應(yīng)。
// 1:創(chuàng)建序列
let behaviorRelay = BehaviorRelay(value: 1)
// 3:訂閱序列
behaviorRelay.subscribe(onNext: { (num) in
print(num)
})
.disposed(by: disposbag)
print("accept前:\(behaviorRelay.value)")
// 2:發(fā)送信號
behaviorRelay.accept(100)
print("accept后:\(behaviorRelay.value)")
1
accept前:1
100
accept后:100
訂閱到了: completed
