Subjects And Variables

  • Subjects

1、Subjects 既是訂閱者消请,也是 Observable
2杂腰、一共有四種 Subjects复亏,分別為:PublishSubject趾娃、BehaviorSubject、ReplaySubject缔御、Variable抬闷。他們之間既有各自的特點,也有相同之處:
  • 首先他們都是 Observable耕突,他們的訂閱者都能收到他們發(fā)出的新的 Event笤成。
  • 直到 Subject 發(fā)出 .complete 或者 .error 的 Event 后,該 Subject 便終結了眷茁,同時它也就不會再發(fā)出 .next 事件炕泳。
  • 對于那些在 Subject 終結后再訂閱他的訂閱者,也能收到 subject 發(fā)出的一條 .complete 或 .error 的 event上祈,告訴這個新的訂閱者它已經終結了培遵。
  • 他們之間最大的區(qū)別只是在于:當一個新的訂閱者剛訂閱它的時候挣磨,能不能收到 Subject 以前發(fā)出過的舊 Event,如果能的話又能收到多少個荤懂。
3、Subject 常用的幾個方法:
  • onNext(:):是 on(.next(:)) 的簡便寫法塘砸。該方法相當于 subject 接收到一個 .next 事件节仿。
  • onError(:):是 on(.error(:)) 的簡便寫法。該方法相當于 subject 接收到一個 .error 事件掉蔬。
  • onCompleted():是 on(.completed) 的簡便寫法廊宪。該方法相當于 subject 接收到一個 .completed 事件。
  • PublishSubject

    PublishSubject 的訂閱者從他們開始訂閱的時間點起女轿,可以收到訂閱后 Subject 發(fā)出的新 Event箭启,而不會收到他們在訂閱前已發(fā)出的 Event
//創(chuàng)建一個PublishSubject
let subject = PublishSubject<String>()
 
//由于當前沒有任何訂閱者,所以這條信息不會輸出到控制臺
subject.onNext("111")
 
//第1次訂閱subject
subject.subscribe(onNext: { string in
    print("第1次訂閱:", string)
}, onCompleted:{
    print("第1次訂閱:onCompleted")
}).disposed(by: disposeBag)
  • BehaviorSubject

BehaviorSubject 需要通過一個默認初始值來創(chuàng)建
當一個訂閱者來訂閱它的時候蛉迹,這個訂閱者會立即收到 BehaviorSubjects 上一個 發(fā)出的 event傅寡。之后就跟正常的情況一樣,它也會接收到 BehaviorSubject 之后發(fā)出的新的 event

//創(chuàng)建一個BehaviorSubject
let subject = BehaviorSubject(value: "111")
 
//第1次訂閱subject
subject.subscribe { event in
    print("第1次訂閱:", event)
}.disposed(by: disposeBag)
  • ReplaySubject

ReplaySubject 在創(chuàng)建時候需要設置一個 bufferSize北救,表示它對于它發(fā)送過的 event 的緩存?zhèn)€數(shù)
比如一個 ReplaySubject 的 bufferSize 設置為 2荐操,它發(fā)出了 3 個 .next 的 event,那么它會將后兩個(最近的兩個)event 給緩存起來珍策。此時如果有一個 subscriber 訂閱了這個 ReplaySubject托启,那么這個 subscriber 就會立即收到前面緩存的兩個 .next 的 event
如果一個 subscriber 訂閱已經結束的 ReplaySubject,除了會收到緩存的 .next 的 event 外攘宙,還會收到那個終結的 .error 或者 .complete 的 event

//創(chuàng)建一個bufferSize為2的ReplaySubject
let subject = ReplaySubject<String>.create(bufferSize: 2)
 
//連續(xù)發(fā)送3個next事件
subject.onNext("111")
subject.onNext("222")
subject.onNext("333")
 
//第1次訂閱subject
subject.subscribe { event in
    print("第1次訂閱:", event)
}.disposed(by: disposeBag)
  • Variable

(注意:由于 Variable 在之后版本中將被廢棄屯耸,建議使用 Varible 的地方都改用下面介紹的 BehaviorRelay 作為替代)
Variable 其實就是對 BehaviorSubject 的封裝,所以它也必須要通過一個默認的初始值進行創(chuàng)建
Variable 具有 BehaviorSubject 的功能蹭劈,能夠向它的訂閱者發(fā)出上一個 event 以及之后新創(chuàng)建的 event
不同的是疗绣,Variable 還把會把當前發(fā)出的值保存為自己的狀態(tài)。同時它會在銷毀時自動發(fā)送 .complete 的 event铺韧,不需要也不能手動給 Variables 發(fā)送 completed 或者 error 事件來結束它
簡單地說就是 Variable 有一個 value 屬性持痰,我們改變這個 value 屬性的值就相當于調用一般 Subjects 的 onNext() 方法,而這個最新的 onNext() 的值就被保存在 value 屬性里了祟蚀,直到我們再次修改它

Variables 本身沒有 subscribe() 方法工窍,但是所有 Subjects 都有一個 asObservable() 方法。我們可以使用這個方法返回這個 Variable 的 Observable 類型前酿,拿到這個 Observable 類型我們就能訂閱它了患雏。

//創(chuàng)建一個初始值為111的Variable
let variable = Variable("111")
         
//修改value值
variable.value = "222"
         
//第1次訂閱
variable.asObservable().subscribe {
    print("第1次訂閱:", $0)
}.disposed(by: disposeBag)
         
//修改value值
variable.value = "333"
  • BehaviorRelay

BehaviorRelay 是作為 Variable 的替代者出現(xiàn)的。它的本質其實也是對 BehaviorSubject 的封裝罢维,所以它也必須要通過一個默認的初始值進行創(chuàng)建
BehaviorRelay 具有 BehaviorSubject 的功能淹仑,能夠向它的訂閱者發(fā)出上一個 event 以及之后新創(chuàng)建的 event
與 BehaviorSubject 不同的是,BehaviorRelay 會在銷毀時自動發(fā)送 .complete 的 event,不需要也不能手動給 BehaviorReply 發(fā)送 completed 或者 error 事件來結束它
BehaviorRelay 有一個 value 屬性匀借,我們通過這個屬性可以獲取最新值颜阐。而通過它的 accept() 方法可以對值進行修改

//創(chuàng)建一個初始值為111的BehaviorRelay
let subject = BehaviorRelay<String>(value: "111")
         
//修改value值
subject.accept("222")
         
//第1次訂閱
subject.asObservable().subscribe {
    print("第1次訂閱:", $0)
}.disposed(by: disposeBag)
         
//修改value值
subject.accept("333")
如果想將新值合并到原值上,可以通過 accept() 方法與 value 屬性配合來實現(xiàn)吓肋。(這個常用在表格上拉加載功能上凳怨,BehaviorRelay 用來保存所有加載到的數(shù)據)
//創(chuàng)建一個初始值為包含一個元素的數(shù)組的BehaviorRelay
let subject = BehaviorRelay<[String]>(value: ["1"])
         
//修改value值
subject.accept(subject.value + ["2", "3"])
         
//第1次訂閱
subject.asObservable().subscribe {
    print("第1次訂閱:", $0)
}.disposed(by: disposeBag)
         
//修改value值
subject.accept(subject.value + ["4", "5"])

參考文章:Swift - RxSwift的使用詳解7(Subjects、Variables)

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末是鬼,一起剝皮案震驚了整個濱河市肤舞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌均蜜,老刑警劉巖李剖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異囤耳,居然都是意外死亡篙顺,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門充择,熙熙樓的掌柜王于貴愁眉苦臉地迎上來慰安,“玉大人,你說我怎么就攤上這事聪铺』溃” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵铃剔,是天一觀的道長撒桨。 經常有香客問我,道長键兜,這世上最難降的妖魔是什么凤类? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮普气,結果婚禮上谜疤,老公的妹妹穿的比我還像新娘。我一直安慰自己现诀,他們只是感情好夷磕,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著仔沿,像睡著了一般坐桩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上封锉,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天绵跷,我揣著相機與錄音膘螟,去河邊找鬼。 笑死碾局,一個胖子當著我的面吹牛荆残,可吹牛的內容都是我干的。 我是一名探鬼主播净当,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼内斯,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蚯瞧?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤品擎,失蹤者是張志新(化名)和其女友劉穎埋合,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體萄传,經...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡甚颂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了秀菱。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片振诬。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖衍菱,靈堂內的尸體忽然破棺而出赶么,到底是詐尸還是另有隱情,我是刑警寧澤脊串,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布辫呻,位于F島的核電站,受9級特大地震影響琼锋,放射性物質發(fā)生泄漏放闺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一缕坎、第九天 我趴在偏房一處隱蔽的房頂上張望怖侦。 院中可真熱鬧,春花似錦谜叹、人聲如沸匾寝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽旗吁。三九已至,卻和暖如春停局,著一層夾襖步出監(jiān)牢的瞬間很钓,已是汗流浹背香府。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留码倦,地道東北人企孩。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像袁稽,于是被迫代替她去往敵國和親勿璃。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內容