PublishSubject
๐ข PublishSubject โ ๊ฐ์ฅ ๊ธฐ๋ณธ์ด ๋๋ Hot Subject
ํต์ฌ ํค์๋: ๊ตฌ๋ ์ดํ ์ด๋ฒคํธ๋ง ์ ๋ฌ ยท ์ด๊ธฐ๊ฐ ์์ ยท Completed/Error ํ ์์ฒด ์๋ฉธ
PublishSubject<Element>
๋ Cold Observable๊ณผ Observer ์์ชฝ ์ญํ ์ ๋ชจ๋ ์ํํ๋ Hot ์คํธ๋ฆผ์
๋๋ค. ๊ตฌ๋
์์ ์ด์ ์ด๋ฒคํธ๋ ์ ๋ฌํ์ง ์๊ธฐ ๋๋ฌธ์ ์๋ฆผ(Notification) ํจํด์ ์ ํฉํฉ๋๋ค.
1๏ธโฃ ํน์ง ํ๋์ ๋ณด๊ธฐ
์ด๊ธฐ๊ฐ
โ ์์
ํ์ํ๋ฉด BehaviorSubject
๊ณ ๋ ค
์บ์
โ ์ ๋ฌ๋ ๊ฐ ์ ์ฅ X
ReplaySubject
์ฐธ์กฐ
Hot/Cold
Hot
๊ตฌ๋ ์ด์ ์ด๋ฒคํธ ์์ค ๊ฐ๋ฅ
์๋ฃ ์ด๋ฒคํธ
.onCompleted()
/ .onError()
๋ฐ์ ์ ์คํธ๋ฆผ ์ข
๋ฃ & ๋ชจ๋ ๊ตฌ๋
์์ ์ ํ
๋ฉ๋ชจ๋ฆฌ
์๋ฃ ํ ๋ด๋ถ ๋ฒํผ ํด์
์ฃผ์ ๊ฐ ๋์ ์ํ ๋ฎ์
2๏ธโฃ ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
let subject = PublishSubject<String>()
let bag = DisposeBag()
// 1st ๊ตฌ๋
์
subject
.subscribe(onNext: { print("๐
ฐ๏ธ:",$0) })
.disposed(by: bag)
subject.onNext("Hello")
// 2nd ๊ตฌ๋
์ (์ด ์์ ์ด์ ๊ฐ ๋ฐ์ง ๋ชปํจ)
subject
.subscribe(onNext: { print("๐
ฑ๏ธ:",$0) })
.disposed(by: bag)
subject.onNext("RxSwift")
subject.onCompleted()
์ถ๋ ฅ
๐
ฐ๏ธ: Hello
๐
ฐ๏ธ: RxSwift
๐
ฑ๏ธ: RxSwift
๋ ๋ฒ์งธ ๊ตฌ๋ ์๋ "Hello"๋ฅผ ๋ฐ์ง ๋ชปํจ (Hot ํน์ฑ).
onCompleted()
์ดํ์ ์๋ก์ด ์ด๋ฒคํธ๊ฐ ์ ๋ฌ๋์ง ์์ผ๋ฉฐ, ์ถ๊ฐ ๊ตฌ๋ ์.completed
์ฆ์ ์์ .
3๏ธโฃ UI & ViewModel ํจํด ์์ โ ๋ฒํผ ํญ ์ด๋ฒคํธ ๋ธ๋ก๋์บ์คํ
final class MenuViewModel {
// ์ธ๋ถ์ ๋
ธ์ถํ readonly Observable
let itemSelected: Observable<Int>
private let itemSelectedSubject = PublishSubject<Int>()
private let bag = DisposeBag()
init(input: (buttonTap: Observable<Int>)) {
self.itemSelected = itemSelectedSubject.asObservable()
input.buttonTap
.bind(to: itemSelectedSubject) // View โถ๏ธ ViewModel
.disposed(by: bag)
}
}
์ฌ๋ฌ ๊ตฌ๋ ์(๋ค๋น๊ฒ์ด์ , ๋ก๊ทธ ๋ชจ๋ ๋ฑ)๊ฐ
itemSelected
๋ฅผ ๋ ๋ฆฝ์ ์ผ๋ก ์ฒ๋ฆฌ ๊ฐ๋ฅ.์ด์ ๋ฒํผ ํญ ์ด๋ฒคํธ๋ฅผ ์ฌ์ ์กํ ํ์๊ฐ ์์ผ๋ฏ๋ก
PublishSubject
๊ฐ ์ ํฉ.
4๏ธโฃ ๋ง๋ธ ๋ค์ด์ด๊ทธ๋จ ๋น๊ต
PublishSubject
โ
โ
0
BehaviorSubject
โญ (์ต์ 1๊ฐ)
โญ
1
ReplaySubject(3)
โญ (์ต๊ทผ 3๊ฐ)
โ
n
AsyncSubject
โ (์๋ฃ ์ 1๊ฐ)
โ
1 (์๋ฃ ์์ )
5๏ธโฃ ๋ฉ๋ชจ๋ฆฌ & ์ฐ๋ ๋ ์ฃผ์์ฌํญ
retain cycle:
subject.onNext(self)
๊ฐ์ self ์บก์ฒ ์ฃผ์ โ[weak self]
ํจํด ๊ถ์ฅ.์๋ฃ or ์๋ฌ ํ ํด์ : ํ์ ์๋ค๋ฉด
subject.onCompleted()
ํธ์ถํด ๋ฉ๋ชจ๋ฆฌ ํด์ ์์ ๋ช ์.MainScheduler ๋ณด์ฅ: UI ๊ฐ์ ์ ๋ฌํ ๋
observe(on: MainScheduler.instance)
์ ํ.
6๏ธโฃ ์์ฃผ ํ๋ ์ค์ & ํด๊ฒฐ์ฑ
๊ตฌ๋ ์ ์ ์ด๋ฒคํธ ๋ฐํ
์ด๊ธฐ ๊ตฌ๋ ์๊ฐ ๊ฐ ๋ชป ๋ฐ์
๊ตฌ๋
โ ์ด๋ฒคํธ ์์ ํ์ธ ๋๋ BehaviorSubject
์ฌ์ฉ
onError
๋จ๋ฐ
๋ชจ๋ ๊ตฌ๋ ์ข ๋ฃ, ์ฑ ์ํ ๋ถ์์
catchError
๋ก ์๋ฌ ๋ณํ ํ .onNext(Result.failure)
ํจํด
DisposeBag
๋ฒ์ ์ค๋ฅ
์คํธ๋ฆผ ๊ณ์ ์ด์์์
Bag์ VCยทVM ํ๋กํผํฐ๋ก ์ ์ธ, deinit ๋ก๊ทธ ํ์ธ
7๏ธโฃ Mini Quiz
PublishSubject
์ ๊ตฌ๋ ์๊ฐ ์์ ๋onNext
๋ฅผ ํธ์ถํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น?.onError
ํธ์ถ ๋คonNext
๋ฅผ ๋ค์ ๋ณด๋ด๋ฉด?๋์ผ ๊ธฐ๋ฅ ๊ตฌํ ์
PassthroughSubject
(Combine)์ ๋ค๋ฅธ ์ ํ ๊ฐ์ง?
๋ค์ ๋ฌธ์ โถ๏ธ BehaviorSubject ๋ก ์ด๋ํ์ฌ ์ต์ ๊ฐ ๋ณด์กด ์ ๋ต์ ํ์ตํด ๋ณด์ธ์. ๐
Last updated