Subject介紹
- Subject 既是 Observer 也是 Observable 。它可以訂閱一個(gè)或多個(gè) Observable,當(dāng)收到消息后進(jìn)行處理,也可以通過Event將數(shù)據(jù)發(fā)送給訂閱者。
- 一共有四種Subject,PublishSubject、BehaviorSubject、ReplaySubject、BehaviorRelay、Variable(廢棄、用BehaviorRelay替代),他們最大區(qū)別在于:當(dāng)一個(gè)新的訂閱者訂閱它的時(shí)候,能否收到Subject以前發(fā)出過的就的Event,如果可以的會(huì),又能收到多少個(gè)
- PublishSubject
當(dāng)訂閱者訂閱PublishSubject 時(shí),只會(huì)收到訂閱后Subject發(fā)出的新Event,而不會(huì)收到訂閱之前發(fā)出的舊Event
func publishSubject() {
let subject = PublishSubject<String>()
subject.onNext("A") //不會(huì)收到
subject.subscribe(onNext: { element in
print("第1次訂閱:", element)
}, onCompleted: {
print("第1次訂閱:completed")
}).disposed(by: bag)
subject.onNext("B") //1訂閱收到
subject.subscribe(onNext: { element in
print("第2次訂閱:", element)
}, onCompleted: {
print("第2次訂閱:completed")
}).disposed(by: bag)
subject.onNext("C") //1、2訂閱會(huì)收到
subject.onNext("D") //1、2訂閱會(huì)收到
subject.onCompleted() //所有的訂閱都會(huì)收到
subject.onNext("F") //不會(huì)收到
//subject完成后,所有的訂閱,包括完成后的訂閱,都會(huì)收到.completed事件
subject.subscribe(onNext: { element in
print("第3次訂閱:", element)
}, onCompleted: {
print("第3次訂閱:completed")
}).disposed(by: bag)
}
運(yùn)行結(jié)果:
第1次訂閱: B
第1次訂閱: C
第2次訂閱: C
第1次訂閱: D
第2次訂閱: D
第1次訂閱:completed
第2次訂閱:completed
第3次訂閱:completed
- BehaviorSubject
BehaviorSubject 通過一個(gè)默認(rèn)初始值來創(chuàng)建,當(dāng)訂閱者訂閱BehaviorSubject 時(shí),會(huì)收到訂閱后Subject上一個(gè)發(fā)出的Event,如果還沒有收到任何數(shù)據(jù),會(huì)發(fā)出一個(gè)默認(rèn)值。之后就和PublishSubject 一樣,正常接收新的事件。
func behaviorSubject() {
let subject = BehaviorSubject(value: "A")
subject.subscribe(onNext: { element in
print("第1次訂閱:", element)
}, onCompleted: {
print("第1次訂閱:completed")
}).disposed(by: bag)
subject.onNext("B")
subject.subscribe(onNext: { element in
print("第2次訂閱:", element)
}, onCompleted: {
print("第2次訂閱:completed")
}).disposed(by: bag)
subject.onNext("C") //1、2訂閱會(huì)收到
subject.onNext("D") //1、2訂閱會(huì)收到
subject.onCompleted() //所有的訂閱都會(huì)收到
subject.onNext("F") //不會(huì)收到
//subject完成后,所有的訂閱,包括完成后的訂閱,都會(huì)收到.completed事件
subject.subscribe(onNext: { element in
print("第3次訂閱:", element)
}, onCompleted: {
print("第3次訂閱:completed")
}).disposed(by: bag)
}
運(yùn)行結(jié)果:
第1次訂閱: A
第1次訂閱: B
第2次訂閱: B
第1次訂閱: C
第2次訂閱: C
第1次訂閱: D
第2次訂閱: D
第1次訂閱:completed
第2次訂閱:completed
第3次訂閱:completed
- ReplaySubject
ReplaySubject 創(chuàng)建的時(shí)候需要設(shè)置一個(gè) buffSize,用來表示發(fā)出過的Event的緩存?zhèn)€數(shù)。當(dāng)一個(gè)訂閱者訂閱了一個(gè) ReplaySubject 之后,他將會(huì)收到當(dāng)前緩存在 buffer 中的數(shù)據(jù)和這之后產(chǎn)生的新數(shù)據(jù)。如果訂閱者訂閱了一個(gè)已經(jīng)結(jié)束的ReplaySubject,除了會(huì)收到緩存中的 next 的Event,還會(huì)收到那個(gè)終結(jié)的 error或 completed 的Event
func replaySubject() {
let subject = ReplaySubject<String>.create(bufferSize: 2)
subject.subscribe(onNext: { element in
print("第1次訂閱:", element)
}, onCompleted: {
print("第1次訂閱:completed")
}).disposed(by: bag)
subject.onNext("A")
subject.onNext("B")
subject.subscribe(onNext: { element in
print("第2次訂閱:", element)
}, onCompleted: {
print("第2次訂閱:completed")
}).disposed(by: bag)
subject.onNext("C")
subject.onCompleted()
subject.onNext("D") //不會(huì)收到
//subject完成后,所有的訂閱,包括完成后的訂閱,都會(huì)收到.completed事件
subject.subscribe(onNext: { element in
print("第3次訂閱:", element)
}, onCompleted: {
print("第3次訂閱:completed")
}).disposed(by: bag)
}
運(yùn)行結(jié)果:
第1次訂閱: A
第1次訂閱: B
第2次訂閱: A
第2次訂閱: B
第1次訂閱: C
第2次訂閱: C
第1次訂閱:completed
第2次訂閱:completed
第3次訂閱: B
第3次訂閱: C
第3次訂閱:completed
- Variable (deprecated)
Variable 封裝了 BehaviorSubject。使用 variable 的好處是 variable 將不會(huì)顯式的發(fā)送 Error 或者 Completed。在 deallocated 的時(shí)候,Variable 會(huì)自動(dòng)的發(fā)送 complete 事件。
使用Variable的時(shí)候會(huì)打印提示:Variable is planned for future deprecation. Please consider BehaviorRelay as a replacement
func variable() {
let variable = Variable("A")
variable.asObservable().subscribe(onNext: { element in
print("第1次訂閱:", element)
}, onCompleted: {
print("第1次訂閱:completed")
}).disposed(by: bag)
variable.value = "B"
variable.asObservable().subscribe(onNext: { element in
print("第2次訂閱:", element)
}, onCompleted: {
print("第2次訂閱:completed")
}).disposed(by: bag)
variable.value = "C"
}
運(yùn)行結(jié)果:
第1次訂閱: A
第1次訂閱: B
第2次訂閱: B
第1次訂閱: C
第2次訂閱: C
第1次訂閱:completed
第2次訂閱:completed
- BehaviorRelay
BehaviorRelay 作為Variable 的替代者出現(xiàn),本質(zhì)上也是對(duì)BehaviorSubject的封裝。不同的是Variable他不是觀察者也不是序列,沒有任何繼承。 BehaviorRelay 只遵守 ObservableType協(xié)議,所以它其實(shí)是一個(gè)序列,但它有一個(gè)value 屬性,通過這屬性能拿到最新的值。而通過它的 accept() 方法可以對(duì)值進(jìn)行修改,通過它里面的subject將修改的值發(fā)送出去。
func behaviorRelay() {
let subject = BehaviorRelay(value: "A")
subject.asObservable().subscribe(onNext: { element in
print("第1次訂閱:", element)
}, onCompleted: {
print("第1次訂閱:completed")
}).disposed(by: bag)
subject.accept("B")
subject.asObservable().subscribe(onNext: { element in
print("第2次訂閱:", element)
}, onCompleted: {
print("第2次訂閱:completed")
}).disposed(by: bag)
subject.accept("C")
}
運(yùn)行結(jié)果:
第1次訂閱: A
第1次訂閱: B
第2次訂閱: B
第1次訂閱: C
第2次訂閱: C