iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 7
0
Mobile Development

RxSwift / 30天探索之旅系列 第 7

第 7 天 - Relay

  • 分享至 

  • xImage
  •  

嗨!今天過得好嗎?昨天介紹三種Subject,今天要介紹跟Subject很像的Relay,它也算是Subject的一種,讓我們開始吧。

PublishRelay

定義『只接受.next事件,不接受.error.completed』,換句話說,它不會中斷,從source code來看,PublishRelay其實就是PublishSubject再包一層,因為只能接收.next,所以語法變成.accept了。

public func accept(_ event: Element) {
	  self._subject.onNext(event)
}

看一下範例程式

let subject = PublishRelay<String>()

subject.accept("1")

subject
    .debug("A")
    .subscribe()
    .disposed(by: disposeBag)

subject.accept("2")

subject.accept("3")

執行結果如下,是不是跟PublishSubject很像呢!

A -> subscribed
A -> Event next(2)
A -> Event next(3)

BehaviorRelay

定義的部分跟PublishRelay一樣,BehaviorRelay就是BehaviorSubject的封裝,跟BehaviorSubject一樣有.value()可以使用,但因為Relay不會.error或disposed的問題,自然也不用處理意外狀況。

範例程式如下

let subject = BehaviorRelay<String>(value: "1")

subject
    .debug("A")
    .subscribe()
    .disposed(by: disposeBag)

subject.accept("2")

print(“Relay value: \(subject.value)”)

執行結果如下

A -> subscribed
A -> Event next(1)
A -> Event next(2)
Relay value: 2

怎麼沒有ReplayRelay

不知道有沒有人跟我一樣好奇,怎麼沒看到ReplayRelay,於是我找到這篇
Add ReplayRelay by lordzsolt · Pull Request #2111 · ReactiveX/RxSwift · GitHub
有興趣的人可以細看大神討論內容,結論就是目前已經合併到develop了,就看什麼時候release囉!

Variable(已棄用)

Variable如同他名字一樣,可以透過setting和getting去改變或是取得現在的值,就跟一般的變數沒兩樣,這顯然跟我們第一天說的Rx世界有點違背。

所以在5.x版已被棄用,擷取Shai Mishali大神所說,這是RxSwift早期為了讓大家可以從Imperative到Rx的一個過渡期,一個好意但卻被濫用,導致初衷不在,為了阻止這一切,從4.x版開始警告,也在5.x版正式棄用,且建議以 BehaviorRelay或BehaviorSubject代替。


昨天講了Subject,今天講了Relay,明天聊聊Subject的使用注意事項,已經過一週了,加油!


上一篇
第 6 天 - Subject (下)
下一篇
第 8 天 - 淺談Subject使用時機
系列文
RxSwift / 30天探索之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
t19960804
iT邦新手 5 級 ‧ 2020-11-06 17:25:03

版主你好
請問一下Relay既然不會中斷
那何時會被Dispose呢?

Bing iT邦新手 5 級 ‧ 2020-11-09 17:54:59 檢舉

安安你好,

我理解是這樣的,如果有訂閱Relay,記得要放進disposeBag

relay
    .debug("Relay Event")
    .subscribe()
    .disposed(by: disposeBag)

這樣當deinit()就會去呼叫disposeBag裡面的Disposable的dispose(),所以上面就會收到Relay Event -> isDisposed

t19960804 iT邦新手 5 級 ‧ 2020-11-09 18:10:23 檢舉

感謝版主回答
deinit() > 這個method指的是不是一般class(UIViewController or UIView)中的deinit()?

Bing iT邦新手 5 級 ‧ 2020-11-10 09:57:21 檢舉

嗯嗯,對哦
這段在DisposeBag.swift這檔案裡面,可以搜尋看看,當bag註銷時,會去執行self.dispose()把bag裡面的disposable都執行一次self.dispose()

我要留言

立即登入留言