Search

RxSwift - Subject & Relay

ย Subject

Subject๋Š” โ€œObservable์ด์ž Observerโ€๋ผ๊ณ  ๋งŽ์ด๋“ค ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๋Š” Observable๋กœ์„œ ๋ฐ์ดํ„ฐ๋ฅผ ํƒœ์šฐ๊ณ  ๋‹ค๋‹ Stream๋ฅผ ๊ฐ€์ง€๋ฉด์„œ, Observer๋กœ์„œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์˜ค๋Š”๊ฒŒ ๊ด€์ฐฐ๋˜๋ฉด ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ Stream์— ํƒœ์šด๋‹ค๋Š” ๊ฑธ ๋œปํ•ฉ๋‹ˆ๋‹ค.
์ด์ „์— ์–˜๊ธฐํ–ˆ๋˜ RxSwift - Observable ์€ ์ƒ์„ฑ๋œ Observable์— ์ด๋ฏธ ๋„ฃ์–ด์ง„ ๊ฐ’๋งŒ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ์ด๋Ÿฐ ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ…์ŠคํŠธ ํ•„๋“œ์— ์žˆ๋Š” ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋ฉด ํ•ด๋‹น ๊ฐ’์„ ๋ฐ์ดํ„ฐ๋กœ ๋ณด๋‚ด์ฃผ๋Š” ๊ฑฐ์ฃ . ํ…์ŠคํŠธ ํ•„๋“œ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๊ธฐ ์ „๊นŒ์ง€๋Š” ์–ด๋–ค ๊ฐ’์œผ๋กœ ๋ณ€๊ฒฝ๋  ์ง€ ๋ชจ๋ฅด๊ธฐ ๋•Œ๋ฌธ์— Observable์— ํ•ด๋‹น ๊ฐ’์„ ๋ฏธ๋ฆฌ ๋„˜๊ฒจ์ค„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ฐ’์ด ๋ฐ”๋€Œ๋Š”์ง€ ๊ด€์ฐฐํ•˜๊ณ  ์žˆ์–ด์•ผ ํ•˜๋Š”๊ฒ๋‹ˆ๋‹ค.
์ด๋Ÿฐ ์—ญํ• ์„ ํ•ด์ค„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด Subject์ž…๋‹ˆ๋‹ค.
Subject๋ฅผ ์ƒ์„ฑํ•ด๋‘๋ฉด ํ…์ŠคํŠธ ํ•„๋“œ๊ฐ€ ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค ๊ทธ ๊ฐ’์„ Subject Stream์œผ๋กœ ๋ฐฉ์ถœํ•˜๊ฒŒ๋”ํ•˜์—ฌ Observable์—์„œ ํ•ด๊ฒฐํ•˜์ง€ ๋ชปํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ย Subject์˜ ์ข…๋ฅ˜

PublishSubject

subscribe๋œ ์‹œ์  ์ดํ›„๋ถ€ํ„ฐ ๋ฐœ์ƒํ•œ ์ด๋ฒคํŠธ ์ „๋‹ฌ
PublishSubject๋Š” โ“ต ์ƒ์„ฑ์‹œ ์ดˆ๊ธฐ ๊ฐ’์ด ์—†๋Š” Subject ์ž…๋‹ˆ๋‹ค.
๊ตฌ๋…ํ•œ ์‹œ์ ๋ถ€ํ„ฐ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๊ฐ’์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ณ , Subject๊ฐ€ ์™„์ „ํžˆ ์ข…๋ฃŒํ•˜๊ณ  ๋‚˜๋ฉด ์ƒˆ๋กœ์šด ๊ตฌ๋…์ž๊ฐ€ ์ƒ๊ธด๋‹ค๊ณ  ํ•ด๋„ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ข…๋ฃŒ ํ›„์—” ์›๋ž˜ ๊ตฌ๋…ํ•˜๊ณ  ์žˆ๋˜ ๊ตฌ๋…์ž์™€ ์ข…๋ฃŒ ์ดํ›„ ๊ตฌ๋…์ž ๋ชจ๋‘์—๊ฒŒ ์ข…๋ฃŒ ์ด๋ฒคํŠธ์™€ ์•Œ๋ฆผ์„ ์ค๋‹ˆ๋‹ค.
let ๊ธ‰์‹์•„์คŒ๋งˆ = PublishSubject<String>() let disposeBag = DisposeBag() let ํ•™์ƒA = ๊ธ‰์‹์•„์คŒ๋งˆ .subscribe(onNext: { (food) in print("ํ•™์ƒA๊ฐ€ ๋ƒ ๋ƒ  ๋จน์€ ",food) }, onError: { (error) in print("Erorr: ",error) }, onCompleted: { print("ํ•™์ƒA ์ด์ œ ๋") }) .disposed(by: disposeBag) ๊ธ‰์‹์•„์คŒ๋งˆ.onNext("๋งŒ๋‘") ๊ธ‰์‹์•„์คŒ๋งˆ.onNext("์น˜ํ‚จ") ๊ธ‰์‹์•„์คŒ๋งˆ.onCompleted() // ์•„์ฃผ๋จธ๋‹ˆ ํ‡ด๊ทผ let ํ•™์ƒB = ๊ธ‰์‹์•„์คŒ๋งˆ .subscribe(onNext: { (food) in print("ํ•™์ƒB๊ฐ€ ๋ƒ ๋ƒ  ๋จน์€ ",food) }, onError: { (error) in print("Erorr: ",error) }, onCompleted: { print("ํ•™์ƒB ์ด์ œ ๋") }) .disposed(by: disposeBag) ๊ธ‰์‹์•„์คŒ๋งˆ.onNext("์ŠคํŒŒ๊ฒŒํ‹ฐ") ๊ธ‰์‹์•„์คŒ๋งˆ.onNext("๊ณฑ์ฐฝ") ๊ธ‰์‹์•„์คŒ๋งˆ.onNext("๋Œ€๋ฐฉ์–ด") /* ํ•™์ƒA๊ฐ€ ๋ƒ ๋ƒ  ๋จน์€ ๋งŒ๋‘ ํ•™์ƒA๊ฐ€ ๋ƒ ๋ƒ  ๋จน์€ ์น˜ํ‚จ ํ•™์ƒA ์ด์ œ ๋ ํ•™์ƒB ์ด์ œ ๋ */
Swift
๋ณต์‚ฌ

BehaviorSubject

subscribe๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ฆ‰์‹œ ํ˜„์žฌ ์ €์žฅํ•œ ๊ฐ’์„ ์ด๋ฒคํŠธ๋กœ ์ „๋‹ฌ
BehaviorSubject๋Š” โ“ต PublishSubject์™€ ๋น„์Šทํ•˜์ง€๋งŒ ์ดˆ๊ธฐ๊ฐ’์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
BehaviorSubject๋ฅผ subscribeํ•˜๋ฉด ์ฆ‰์‹œ ์ดˆ๊ธฐ๊ฐ’์„ ์ด๋ฒคํŠธ๋กœ ์ „๋‹ฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ดˆ๊ธฐ๊ฐ’์ด ์—†๋Š” ์ƒํƒœ์—์„œ๋Š” default๊ฐ’์„ ์ „๋‹ฌํ•˜๊ณ , ์ดˆ๊ธฐ๊ฐ’์ด ์žˆ๋‹ค๋ฉด ์ตœ๊ทผ๊ฐ’(ํ•ญ์ƒ ์ง์ „์˜ ๊ฐ’๋ถ€ํ„ฐ ๊ตฌ๋…)์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ์ดˆ๊ธฐ๊ฐ’์ด ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๋ฉด ๊ทธ๋ƒฅ PublishSubject๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ์ข‹์Šต๋‹ˆ๋‹ค.
BehaviorSubject๋Š” ๋‹ค๋ฅธ Subject์™€๋Š” ๋‹ค๋ฅด๊ฒŒ โ“ถ ๋งˆ์ง€๋ง‰ ์ด๋ฒคํŠธ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, ๊ฐ’์„ ์ €์žฅํ•ด๋‘๊ณ  ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„ ๋•Œ๋Š” BehaviorSubject๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
let ๊ธ‰์‹์•„์คŒ๋งˆ = BehaviorSubject(value: "๋Œ€๋ฐฉ์–ด") let disposeBag = DisposeBag() let ํ•™์ƒA = ๊ธ‰์‹์•„์คŒ๋งˆ .subscribe(onNext: { (food) in print("ํ•™์ƒA๊ฐ€ ๋ƒ ๋ƒ  ๋จน์€ ",food) }, onError: { (error) in print("Erorr: ",error) }, onCompleted: { print("ํ•™์ƒA ์ด์ œ ๋") }) .disposed(by: disposeBag) ๊ธ‰์‹์•„์คŒ๋งˆ.onNext("์†Œ๊ณ ๊ธฐ") ๊ธ‰์‹์•„์คŒ๋งˆ.onNext("ํ”ผ์ž") ๊ธ‰์‹์•„์คŒ๋งˆ.onNext("์ผ€์ดํฌ") let ํ•™์ƒB = ๊ธ‰์‹์•„์คŒ๋งˆ .subscribe(onNext: { (food) in print("ํ•™์ƒB๊ฐ€ ๋ƒ ๋ƒ  ๋จน์€ ",food) }, onError: { (error) in print("Erorr: ",error) }, onCompleted: { print("ํ•™์ƒB ์ด์ œ ๋") }) .disposed(by: disposeBag) ๊ธ‰์‹์•„์คŒ๋งˆ.onNext("์ƒŒ๋“œ์œ„์น˜") ๊ธ‰์‹์•„์คŒ๋งˆ.onNext("์š”ํ”Œ๋ ˆ") /* ํ•™์ƒA๊ฐ€ ๋ƒ ๋ƒ  ๋จน์€ ๋Œ€๋ฐฉ์–ด /// default value ์ „๋‹ฌ ํ•™์ƒA๊ฐ€ ๋ƒ ๋ƒ  ๋จน์€ ์†Œ๊ณ ๊ธฐ ํ•™์ƒA๊ฐ€ ๋ƒ ๋ƒ  ๋จน์€ ํ”ผ์ž ํ•™์ƒA๊ฐ€ ๋ƒ ๋ƒ  ๋จน์€ ์ผ€์ดํฌ ํ•™์ƒB๊ฐ€ ๋ƒ ๋ƒ  ๋จน์€ ์ผ€์ดํฌ /// ์ตœ๊ทผ ๊ฐ’ ์ „๋‹ฌ ํ•™์ƒA๊ฐ€ ๋ƒ ๋ƒ  ๋จน์€ ์ƒŒ๋“œ์œ„์น˜ ํ•™์ƒB๊ฐ€ ๋ƒ ๋ƒ  ๋จน์€ ์ƒŒ๋“œ์œ„์น˜ ํ•™์ƒA๊ฐ€ ๋ƒ ๋ƒ  ๋จน์€ ์š”ํ”Œ๋ ˆ ํ•™์ƒB๊ฐ€ ๋ƒ ๋ƒ  ๋จน์€ ์š”ํ”Œ๋ ˆ */
Swift
๋ณต์‚ฌ

ReplaySubject

n๊ฐœ์˜ ์ด๋ฒคํŠธ๋ฅผ ์ €์žฅํ•˜๊ณ  subscribe๊ฐ€ ๋˜๋Š” ์‹œ์ ๊ณผ ์ƒ๊ด€์—†์ด ์ €์žฅํ•œ ๋ชจ๋“  ์ด๋ฒคํŠธ๋ฅผ ์ „๋‹ฌ
ReplaySubject๋Š” โ“ต ๊ตฌ๋… ์ด์ „์— ์žˆ์—ˆ๋˜ ์ด๋ฒคํŠธ๋ฅผ ๋‹ค ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒ์„ฑ ์‹œ์— ์„ ํƒํ•œ ํŠน์ • ํฌ๊ธฐ๋งŒํผ ์ผ์‹œ์ ์œผ๋กœ ์ด๋ฒคํŠธ๋ฅผ ์บ์‹œํ•˜๊ฑฐ๋‚˜ ๋ฒ„ํผ์— ์ €์žฅํ•ด์„œ ์ตœ์‹  ์š”์†Œ๋ฅผ ๋ชจ๋‘ ๋ฐฉ์ถœํ•ฉ๋‹ˆ๋‹ค.
โ“ถ ๋ฒ„ํผ์˜ ํฌ๊ธฐ๋Š” ์„ค์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋งŒ์•ฝ ๋ฒ„ํผ์˜ ํฌ๊ธฐ๊ฐ€ 0์ด๋ฉด PublishSubject์™€ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํฌ๊ฒŒ ์ฐจ์ง€ํ•˜๋Š” ๊ฐ’์ด๋ผ๋ฉด ๋ฉ”๋ชจ๋ฆฌ ๋ถ€ํ•˜๊ฐ€ ๋‚  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
ReplaySubject๋Š” create(bufferSize: Int), createUnbounded ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ€์ง€๋Š”๋ฐ, ์–ด๋–ค ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š๋ƒ์— ๋”ฐ๋ผ์„œ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค.
โ€ข
create(bufferSize: Int)
let ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜ = ReplaySubject<String>.create(bufferSize: 2) let disposeBag = DisposeBag() ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜.onNext("ํ•œ์ž") ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜.onNext("์ˆ˜ํ•™") ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜.onNext("์˜์–ด") let ํ•™์ƒA์˜๋‡Œ = ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜ .subscribe(onNext: { (subject) in print("ํ•™์ƒA๊ฐ€ ๋ฐฐ์šด ",subject) }, onError: { (error) in print("Erorr: ",error) }, onCompleted: { print("ํ•™์ƒA ์ด์ œ ๊ณต๋ถ€ ๋") }) .disposed(by: disposeBag) let ํ•™์ƒB์˜๋‡Œ = ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜ .subscribe(onNext: { (subject) in print("ํ•™์ƒB๊ฐ€ ๋ฐฐ์šด ",subject) }, onError: { (error) in print("Erorr: ",error) }, onCompleted: { print("ํ•™์ƒB ์ด์ œ ๊ณต๋ถ€ ๋") }) .disposed(by: disposeBag) // ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜์ด ์•„์ด๋“ค์—๊ฒŒ ๋‹จ๋‹จํžˆ ์•Œ๋ ค์ค„ ์ˆ˜ ์žˆ๋Š” ์–‘์ด 2๊ณผ๋ชฉ์œผ๋กœ ํ•œ์ • /* ํ•™์ƒA๊ฐ€ ๋ฐฐ์šด ์ˆ˜ํ•™ ํ•™์ƒA๊ฐ€ ๋ฐฐ์šด ์˜์–ด ํ•™์ƒB๊ฐ€ ๋ฐฐ์šด ์ˆ˜ํ•™ ํ•™์ƒB๊ฐ€ ๋ฐฐ์šด ์˜์–ด */
Swift
๋ณต์‚ฌ
โ€ข
createUnbounded
let ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜ = ReplaySubject<String>.createUnbounded() let disposeBag = DisposeBag() ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜.onNext("ํ•œ์ž") ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜.onNext("์ˆ˜ํ•™") ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜.onNext("์˜์–ด") let ํ•™์ƒA์˜๋‡Œ = ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜ .subscribe(onNext: { (subject) in print("ํ•™์ƒA๊ฐ€ ๋ฐฐ์šด ",subject) }, onError: { (error) in print("Erorr: ",error) }, onCompleted: { print("ํ•™์ƒA ์ด์ œ ๊ณต๋ถ€ ๋") }) .disposed(by: disposeBag) let ํ•™์ƒB์˜๋‡Œ = ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜ .subscribe(onNext: { (subject) in print("ํ•™์ƒB๊ฐ€ ๋ฐฐ์šด ",subject) }, onError: { (error) in print("Erorr: ",error) }, onCompleted: { print("ํ•™์ƒB ์ด์ œ ๊ณต๋ถ€ ๋") }) .disposed(by: disposeBag) // ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜์ด ์•„์ด๋“ค์—๊ฒŒ ๋ฌด์ œํ•œ์œผ๋กœ ์•Œ๋ ค์ค„ ์ˆ˜ ์žˆ์ง€๋งŒ // ํ•™์ƒ๋“ค์ด ๊ณผ๋ถ€ํ•˜์— ๊ฑธ๋ ค์„œ ์•“์•„ ๋ˆ„์šธ ์ˆ˜ ์žˆ์Œ /* ํ•™์ƒA๊ฐ€ ๋ฐฐ์šด ํ•œ์ž ํ•™์ƒA๊ฐ€ ๋ฐฐ์šด ์ˆ˜ํ•™ ํ•™์ƒA๊ฐ€ ๋ฐฐ์šด ์˜์–ด ํ•™์ƒB๊ฐ€ ๋ฐฐ์šด ํ•œ์ž ํ•™์ƒB๊ฐ€ ๋ฐฐ์šด ์ˆ˜ํ•™ ํ•™์ƒB๊ฐ€ ๋ฐฐ์šด ์˜์–ด */
Swift
๋ณต์‚ฌ

AsyncSubject

completed๋  ๋•Œ๊นŒ์ง€ ์•„๋ฌด๋Ÿฐ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋‹ค๊ฐ€, completed๋˜๋ฉด ๋งˆ์ง€๋ง‰ ์ด๋ฒคํŠธ๋ฅผ ์ „๋‹ฌํ•˜๊ณ  ์ข…๋ฃŒ
AsyncSubject๋Š” โ“ต completed๋˜๋Š” ์ˆœ๊ฐ„ ๋งˆ์ง€๋ง‰ ์ด๋ฒคํŠธ๋ฅผ ์ „๋‹ฌํ•˜๊ณ  ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ, ์ตœ๊ทผ ์ „๋‹ฌ๋œ next ์ด๋ฒคํŠธ๊ฐ€ ์—†๋‹ค๋ฉด ๊ทธ๋ƒฅ completed ์ด๋ฒคํŠธ๋งŒ ์ „๋‹ฌํ•˜๊ณ  ์ข…๋ฃŒ๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
completed ์ด๋ฒคํŠธ ๋Œ€์‹  error ์ด๋ฒคํŠธ๋ฅผ ์ „๋‹ฌํ•  ๊ฒฝ์šฐ ์ตœ๊ทผ next ์ด๋ฒคํŠธ๊ฐ€ ์ „๋‹ฌ๋˜์ง€ ์•Š๊ณ , error ์ด๋ฒคํŠธ๋งŒ ์ „๋‹ฌ๋˜๊ณ  ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค.
let ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜ = AsyncSubject<String>() let disposeBag = DisposeBag() ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜.onNext("ํ•œ์ž") ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜.onNext("์ˆ˜ํ•™") ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜.onNext("์˜์–ด") let ํ•™์ƒA์˜๋‡Œ = ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜ .subscribe(onNext: { (subject) in print("ํ•™์ƒA๊ฐ€ ๋ฐฐ์šด ",subject) }, onError: { (error) in print("Erorr: ",error) }, onCompleted: { print("ํ•™์ƒA ์ด์ œ ๊ณต๋ถ€ ๋") }) .disposed(by: disposeBag) let ํ•™์ƒB์˜๋‡Œ = ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜ .subscribe(onNext: { (subject) in print("ํ•™์ƒB๊ฐ€ ๋ฐฐ์šด ",subject) }, onError: { (error) in print("Erorr: ",error) }, onCompleted: { print("ํ•™์ƒB ์ด์ œ ๊ณต๋ถ€ ๋") }) .disposed(by: disposeBag) ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜.onNext("๊ตฌ๋ชฌ์„ ์ƒ๋‹˜์˜ ๋ง›์ง‘ ๋ฆฌ์ŠคํŠธ") ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜.onCompleted() // ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜ ํ‡ด๊ทผ /* ํ•™์ƒA๊ฐ€ ๋ฐฐ์šด ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜์˜ ๋ง›์ง‘ ๋ฆฌ์ŠคํŠธ ํ•™์ƒB๊ฐ€ ๋ฐฐ์šด ๊ตฌ๋ชฌ์„ ์ƒ๋‹˜์˜ ๋ง›์ง‘ ๋ฆฌ์ŠคํŠธ ํ•™์ƒA ์ด์ œ ๊ณต๋ถ€ ๋ ํ•™์ƒB ์ด์ œ ๊ณต๋ถ€ ๋ */
Swift
๋ณต์‚ฌ

ย Relay

Relay๋Š” Subject์™€ ์œ ์‚ฌํ•œ ํŠน์ง•์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ํƒ€์ž…์ž…๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ Relay ํƒ€์ž… ๋‚ด๋ถ€์—์„œ Subject๋ฅผ ๋ž˜ํ•‘ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
public final class PublishRelay<Element>: ObservableType { private let subject: PublishSubject<Element> ... }
Swift
๋ณต์‚ฌ
๊ทธ๋ ‡๋‹ค๋ฉด, Relay์™€ Subject์˜ ์ฐจ์ด๋Š” ๋ญ˜๊นŒ์š”?
์ผ๋‹จ, ๊ฐ€์žฅ ๋ช…ํ™•ํ•œ ์ฐจ์ด๋Š” Subject๋Š” RxSwift์—์„œ, Relay๋Š” RxCocoa์—์„œ ์ œ๊ณตํ•ด์ฃผ๋Š” ํƒ€์ž…์ž…๋‹ˆ๋‹ค.
์™œ Relay๋Š” RxCocoa์—์„œ ์ œ๊ณตํ•ด์ค„๊นŒ์š”?
Relay๋Š” Subject์™€ ์œ ์‚ฌํ•˜์ง€๋งŒ, error, completed ์ด๋ฒคํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
์ฆ‰, ์—๋Ÿฌ๊ฐ€ ๋‚˜๋„ error ์ด๋ฒคํŠธ๋กœ ์ธํ•ด Stream์ด ์ข…๋ฃŒ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— UI๋ฅผ ๊ทธ๋ฆฌ๋Š”๋ฐ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.
Relay๋Š” disposed ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์ „๊นŒ์ง€ ๊ณ„์† ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.
Subject์—์„œ๋Š” next, completed, error ์ด๋ฒคํŠธ๋ฅผ ๋ฐœํ–‰ํ–ˆ์ง€๋งŒ, Relay๋Š” completed, error๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— accept()๋ผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ onNext์—ญํ•  ๋Œ€์‹ ํ•ฉ๋‹ˆ๋‹ค.

ย Relay์˜ ์ข…๋ฅ˜

PublishRelay

PublishSubject๋ฅผ ๋ž˜ํ•‘ํ•œ Relay
ํ•ด๋‹น ํƒ€์ž…์€ PublishSubject์˜ ํŠน์„ฑ์ฒ˜๋Ÿผ ๊ตฌ๋… ์ดํ›„์— ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ๋“ค๋งŒ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋˜ํ•œ, ๋™์ผํ•˜๊ฒŒ ์ดˆ๊ธฐ๊ฐ’์ด ์—†์Šต๋‹ˆ๋‹ค.
let publishRelay = PublishRelay<Int>() publishRelay.subscribe { print($0) } publishRelay.accept(5) /* next(5) */
Swift
๋ณต์‚ฌ

BehaviorRelay

BehaviorSubject๋ฅผ ๋ž˜ํ•‘ํ•œ Relay
์ƒ์„ฑ ์‹œ ํ•˜๋‚˜์˜ default ๊ฐ’์„ ์ €์žฅํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ ์ด BehaviorSubject์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, .value๋ฅผ ํ†ตํ•ด์„œ ๋งˆ์ง€๋ง‰ ์ด๋ฒคํŠธ ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
let behaviorRelay = BehaviorRelay(value: 5) behaviorRelay.accept(6) behaviorRelay.subscribe { print($0) } behaviorRelay.accept(4) print(behaviorRelay.value) /* next(6) next(4) 4 */
Swift
๋ณต์‚ฌ