iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 8
0
Mobile Development

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

第 8 天 - 淺談Subject使用時機

嗨,大家好,今天接著聊聊Subject!

淺談使用時機

Relay在某些情況很好用,比如說在非Rx跟Rx之間的轉換,又或是說,Imperative世界與Rx世界的橋樑,假設像下方這樣

let image = BehaviorRelay<[UIImage]>(value: [])

// 把一組圖片轉成Rx
image.accept(images) 

// 清空image 
image.accept([]) 

// 新增一張圖片
var current = image.value
current.append(newImage)
image.accept(current)

過度使用Subject

Erik Meijer是一個對Rx有莫大貢獻的大神,在網路上能找到許多關於他的影片跟文章,他曾經說過

Subjects are the “mutable variables" of the Rx world and in most cases you do not need them. – Erik Meijer

大意就是說,Subjects是個可變的變數,當你使用Subject或Relay請確定是不是真的需要它,這其他文章也可以看到類似討論 Why Does E.Meijer not like Subjects?Top mistakes in RxSwift you want to avoid - Code in a suit

還記得第一天,我們說Rx世界是Stateless,所有東西就是input跟output,大多數情況都可以用.create搭配其他operator解決,但因為Subject跟Relay太好用了,剛開始我們常常會這樣

Observable
    .subscribe(onNext: {
        observerA.onNext(...)
		observerB.onNext(...)
		observerC.onNext(...)
    })
    .disposed(by: disposeBag)

或是

relay.accept(a)
relay.accept(b)
relay.accept(c)

你會發現,Subject在同個class或是不同class被到處被onNext(),Relay被到處.accept(),這樣我們又回到Imperative思維,並且在Imperative上包一層的感覺,反而更不舒服,寫久了會很亂,也會常常出錯。

我自己呢,因為功力不足,不得已的時候還是會用,但要『切記做好封裝』,封裝成class,對內設為private,想怎麼用都可以,對外是Observable,給外部使用,大概會像這樣

private let imageRelay = BehaviorRelay<[UIImage]>(value: [])
private(set) lazy var image = imageRelay.asObservable()

或是這樣

let image: Observable<[UIImage]>

init() {
    let imageRelay = BehaviorRelay<[UIImage]>(value: [])
    image = imageRelay.asObservable()
}

明天開始進入各種operator的介紹,就這樣,掰掰!


上一篇
第 7 天 - Relay
下一篇
第 9 天 - Filtering Observables
系列文
RxSwift / 30天探索之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言