Search
Duplicate

RxSwift - Dispose, Disposable, DisposeBag

Created
2023/09/15 09:36
Tags
RxSwift

RxSwift - Dispose, Disposable, DisposeBag

ย Disposable๊ณผ dispose()

Dispose - v. ์ฒ˜๋ฆฌํ•˜๋‹ค/์—†์• ๋‹ค
๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ํ˜•ํƒœ Observable์ด ์žˆ์„ ๋•Œ, Observer๋Š” ์ด Observable์„ โ€˜๊ตฌ๋…โ€™์„ ํ†ตํ•ด ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ–ˆ๋‹ค.
โ†’ ์ •ํ™•ํžˆ๋Š” Observer๊ฐ€ Observable์ด ๋ฐฉ์ถœํ•˜๋Š” ํ•ญ๋ชฉ์— ๋Œ€ํ•ด ๋ฐ›๋Š” ๊ฒƒ
๋งŒ์•ฝ ๋”์ด์ƒ ์ด Observable์— ๋Œ€ํ•œ ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›๊ณ  ์‹ถ์ง€ ์•Š์•„์„œ โ€˜๊ตฌ๋…์„ ํ•ด์ œโ€™ ํ•˜๊ณ  ์‹ถ์„ ๋•Œ๋Š”? โ†’ Disposable
ย Subscrib ๋ฉ”์„œ๋“œ ์›ํ˜•
์ด๋ ‡๊ฒŒ ๋ฐ˜ํ™˜ ํƒ€์ž…์ด Disposable ์ธ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
์ฆ‰, subscribe ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๊ฒฝ์šฐ, Observable์„ ๊ตฌ๋…ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ํ•ด๋‹น Observable์˜ ์ด๋ฒคํŠธ๊ฐ€ ๋” ์ด์ƒ ํ•„์š”ํ•˜์ง€ ์•Š์„ ๋•Œ, ํ•ด๋‹น ๊ตฌ๋…์„ ์ทจ์†Œํ•  ์ˆ˜ ์žˆ๋Š” ์ˆ˜๋‹จ์ธ Disposable ์ด๋ž€ ํƒ€์ž…์˜ ๊ฐ’์„ ๋ฆฌํ„ดํ•˜์—ฌ ์ค€๋‹ค.
์ด์ œ ๋ฆฌํ„ด ํƒ€์ž…์ธ Disposable ์„ ์‚ดํŽด๋ณด๋ฉด
public protocol Disposable { func dispose() }
Swift
๋ณต์‚ฌ
์ด๋ ‡๊ฒŒ dispose๋ผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง„ Protocol๋กœ ์ •์˜๋˜์–ด ์žˆ๋‹ค.
Observer๋Š” Observable์„ ๊ตฌ๋…ํ•˜๊ธฐ ์œ„ํ•ด Subscribe๋ผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ์ด Subscribe ๋ฉ”์„œ๋“œ๋Š” ๊ตฌ๋…์„ ํ•ด์ œํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” Disposable์ด๋ž€ ํƒ€์ž…์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค!
๊ทธ๋Ÿฌ๋ฉด ์ด ๋ฆฌํ„ด๋œ Disposable ํƒ€์ž…์˜ ๊ฐ’์— ๋Œ€๊ณ  dispose() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์šฐ๋ฆฌ๊ฐ€ ๊ตฌ๋…ํ•œ Observable์— ๋Œ€ํ•ด ๊ตฌ๋…์„ ํ•ด์ œํ•  ์ˆ˜ ์žˆ๋‹ค!
let hjDisposable = hjButton.rx .tap .subscribe(onNext: { print("hj ๋ฒ„ํŠผ ๋ˆŒ๋ฆผ!") }) hjDieButton.rx .tap .subscribe(onNext: { hjDisposable.dispose() print("hj ๋ฒ„ํŠผ ๊ตฌ๋… ํ•ด์ œ!") })
Swift
๋ณต์‚ฌ
์œ„ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด, hjButton์˜ tap ์ด๋ฒคํŠธ์— ๋Œ€ํ•ด subscribe๋ฅผ ํ†ตํ•ด ๊ตฌ๋…์„ ํ•˜๊ณ , ํ•ด๋‹น ๊ตฌ๋…์„ ์ทจ์†Œํ•  ์ˆ˜ ์žˆ๋Š” ๋ฆฌํ„ด ๊ฐ’, ์ฆ‰ Disposable ์ธ์Šคํ„ด์Šค๋ฅผ hjDisposable์ด๋ž€ ๋ณ€์ˆ˜์— ์ €์žฅํ–ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  hjDieButton์ด ๋ˆŒ๋ ธ์„ ๋•Œ, ์ด hjDisposable์˜ dispose() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด๋ณธ๋‹ค.
hjDieButton์ด ๋ˆŒ๋ฆฌ๊ธฐ ์ „๊นŒ์ง€ ์ž˜ ๋™์ž‘ํ•˜๋˜ hjButton์˜ tap ์ด๋ฒคํŠธ๊ฐ€, hjDieButton์ด ๋ˆŒ๋ฆฌ๋Š” ์ˆœ๊ฐ„ hjButton์˜ tap Observable์— ๋Œ€ํ•œ ๊ตฌ๋…์„ ํ•ด์ œํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์—, ๋”์ด์ƒ hjButton์˜ tap ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜๊ฐ€ ์—†์–ด์ง„๋‹ค.
๋”ฐ๋ผ์„œ ๊ตฌ๋… ํ•ด์ œ ํ›„์— ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๋”์ด์ƒ ์•„๋ฌด๋Ÿฐ ์ด๋ฒคํŠธ๋ฅผ ํ•˜์ง€ ์•Š๊ฒŒ ๋œ๋‹ค.
ย ์š”์•ฝ
Observer๊ฐ€ ์–ด๋–ค Observable์˜ ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›๊ณ  ์‹ถ์„ ๊ฒฝ์šฐ, Subscribe ๋ฉ”์„œ๋“œ๋กœ โ€˜๊ตฌ๋… โ€™์„ ํ†ตํ•ด ํ•  ์ˆ˜ ์žˆ๋‹ค.
ํ•˜์ง€๋งŒ ๋”์ด์ƒ ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›๊ณ  ์‹ถ์ง€ ์•Š์•„์„œ โ€˜๊ตฌ๋…์„ ํ•ด์ œโ€™ ํ•  ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•ด Subscribe ๋ฉ”์„œ๋“œ๋Š” Disposable์ด๋ž€ ํƒ€์ž…์˜ ๋ฆฌํ„ด ๊ฐ’์„ ์ค€๋‹ค.
์ด Disposable์€ ํ”„๋กœํ† ์ฝœ ํƒ€์ž…์œผ๋กœ dispose ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋ฐ, ๋งŒ์•ฝ Observable์ด ๋ฐฉ์ถœํ•˜๋Š” ์ด๋ฒคํŠธ๋ฅผ ๋”์ด์ƒ ๋ฐ›๊ณ  ์‹ถ์ง€ ์•Š์€ ๊ฒฝ์šฐ,
Subscribe๋ฅผ ํ–ˆ์„ ๋•Œ ์–ป์€ ์ด Disposable์— ๋Œ€๊ณ  dispose() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๊ฒฝ์šฐ, ํ•ด๋‹น Observable์— ๋Œ€ํ•œ ๊ตฌ๋…์„ ํ•ด์ œํ•  ์ˆ˜ ์žˆ๋‹ค.
์‚ฌ์‹ค dispose ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฑด, ํ•ด๋‹น ์‹œ์ (๋‚ด๊ฐ€ ์›ํ•˜๋Š” ์‹œ์ )์— ํ•ด๋‹น ์ด๋ฒคํŠธ์˜ ๊ตฌ๋…์„ ๋Š๊ธฐ ์œ„ํ•œ ๊ฒƒ๋„ ์žˆ์ง€๋งŒ, ๊ฐ€์žฅ ์ค‘์š”ํ•œ ์ด์œ  ์ค‘ ํ•˜๋‚˜๋Š” ๋ฐ”๋กœ
๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ
๋ฅผ ์œ„ํ•ด์„œ์ด๋‹ค. Observable์€ ๊ธฐ๋ณธ์ ์œผ๋กœ, complete๋‚˜ error๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์ „๊นŒ์ง„ ๊ณ„์† ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœ ์‹œํ‚ค๋Š”๋ฐ, ๋”ฐ๋ผ์„œ ์ด๋ฒคํŠธ๊ฐ€ ๋”์ด์ƒ ๋ฐฉ์ถœ๋˜๋ฉด ์•ˆ๋˜๋Š” ์‹œ์ ์—์„œ ์šฐ๋ฆฌ๋Š” ์ด ๋ฆฌ์†Œ์Šค๋ฅผ ์ง์ ‘ deinit ํ•ด์ค˜์•ผ ํ•œ๋‹ค.
๋จ„์•ฝ deinit ํ•ด์ฃผ๋Š” ๊ณผ์ •์„ ํ•˜์ง€ ์•Š์œผ๋ฉด, ์ด ๋ฆฌ์†Œ์Šค๋Š” ๊ณ„์†ํ•ด์„œ ํ•„์š”ํ•  ๋–„๋งˆ๋‹ค ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœ์‹œํ‚ค๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋ฆญ(leak) ์œผ๋กœ ์ด์–ด์งˆ๊ฒƒ์ด๋‹ค.
๊ทธ๋Ÿฌ๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด๋‹น Observable๊ณผ ๊ด€๋ จ๋œ ๋ฆฌ์†Œ์Šค๋ฅผ deinit ์‹œํ‚ฌ ์ˆ˜ ์žˆ์„๊นŒ? โ†’ dispose() ๋ฉ”์„œ๋“œ!
Disposable ํƒ€์ž…์˜ ์ธ์Šคํ„ด์Šค์˜ dispose ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค๋Š” ๊ฒƒ์€ ํ•ด๋‹น Observable์— ๋Œ€ํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ deinit ์‹œํ‚จ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์ฆ‰, Rx์—์„œ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋ฅผ ํ•œ๋‹ค๋Š” ๊ฒƒ
โ†’ ์ด๋ ‡๊ฒŒ Rx์—์„œ ์ด dispose๋Š” ๋ฉ”๋ชจ๋ฆฌ์™€ ๊ด€๋ จ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์•„์ฃผ ์ค‘์š”ํ•œ ๋ฉ”์„œ๋“œ์ด๋‹ค.
์˜ˆ๋ฅผ๋“ค๋ฉด
class HjViewController: UIViewController { override func viewDidLoad() { super.veiwDidLoad() let _ = Observable<Int>.interval( .seconds(1), scheduler: MainScheduler.instance ) .subscribe(onNext: { print($0) }) } }
Swift
๋ณต์‚ฌ
HjViewController๊ฐ€ ์‹คํ–‰๋˜๋ฉด, 1์ดˆ์— ํ•œ๋ฒˆ์”ฉ 0๋ถ€ํ„ฐ ์ˆœ์ฐจ์ ์ธ ์ˆซ์ž๋ฅผ ๋ฐฉ์ถœํ•˜๋Š” Observable์„ ๋งŒ๋“ค๊ณ ,
ํ•ด๋‹น Observable์„ ๊ตฌ๋…ํ•˜์—ฌ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐฉ์ถœ๋์„ ๋•Œ, ๊ทธ ์ˆซ์ž๋ฅผ ์ถœ๋ ฅํ•˜๊ฒŒ ํ•œ ๊ฒƒ์ด๋‹ค.
๊ทธ๋ฆฌ๊ณ  ํ•ด๋‹น ๊ตฌ๋…์„ ํ†ตํ•ด ๋ฆฌํ„ด๋ฐ›์€ Disposable ํƒ€์ž…์˜ ์ธ์Šคํ„ด์Šค๋กœ๋Š” ์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š๋Š”๋‹ค.
์ด๋ ‡๊ฒŒ ๋  ๊ฒฝ์šฐ, ์–ด๋–ค ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๋ƒ๋ฉด
HjViewController๊ฐ€ ์ƒ์„ฑ๋˜์–ด ๋„์›Œ์กŒ์„ ๋•Œ, 1์ดˆ์— ํ•œ๋ฒˆ์”ฉ ์ˆœ์ฐจ์ ์ธ ์ˆซ์ž๋ฅผ ๋ฐฉ์ถœํ•˜๋Š” Observable์ด ์ƒ์„ฑ๋˜๊ณ , ํ•ด๋‹น Observable์ด ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœ ํ–ˆ์„ ๋•Œ subscribe ํด๋กœ์ €์— ์˜ํ•ด 0, 1, 2๊ฐ€ ์ฐํžˆ๊ณ  ์žˆ๋‹ค.
ํ•˜์ง€๋งŒ 2๊นŒ์ง€ ์ฐํžˆ๊ณ  ๋‚˜์„œ HjViewController๋ฅผ ๋‚ด๋ ค์„œ, ํ•ด๋‹น Observer์˜ ์ด๋ฒคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋˜ ViewController๊ฐ€ ์•ฑ์—์„œ ์‚ฌ๋ผ์กŒ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ , ํ•ด๋‹น Obserer์— ๋Œ€ํ•œ ๋ฆฌ์†Œ์Šค๊ฐ€ ํ•ด์ œ๋˜์ง€๊ฐ€ ์•Š์•„์„œ, ์ฃฝ์ง€์•Š๊ณ  ๊ณ„์† ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœํ•˜๊ณ  ์žˆ๋Š” ๋ฉ”๋ชจ๋ฆฌ leak๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ์žˆ๋‹ค.
๋”ฐ๋ผ์„œ
class HjViewController: UIViewController { private var timerDisposable: Disposable? override func viewDidLoad() { super.viewDidLoad() timerDisposable = Observable<Int>.interval( .seconds(1) scheduler: MainScheduler.instance ) .subscribe(onNext: { print($0) }) } deinit { timerDisposable?.dispose() } }
Swift
๋ณต์‚ฌ
๋‚˜๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ViewController๊ฐ€ deinit ๋˜๋Š” ์‹œ์ ์— ํ•ด๋‹น Disposable์— ๋Œ€ํ•œ dispose๋ฅผ ํ†ตํ•ด ํ•ด๋‹น Observable ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•ด์„œ๋„ ๊ฐ™์ด deinit์„ ์‹คํ–‰์‹œ์ผœ์ฃผ๋ฉด
ViewController๊ฐ€ deinit ๋  ๋•Œ ํ•ด๋‹น Observable ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ deinit๋„ ๊ฐ™์ด ์ด๋ฃจ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”๋กœ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.

ย DisposeBag

๋ง ๊ทธ๋Œ€๋กœ Disposable์„ ๋‹ด๋Š” Bag์ด๋‹ค.
Observable ๋ฆฌ์†Œ์Šค๊ฐ€ ํ•ด์ œ๋˜์–ด์•ผ ํ•  ์‹œ์ ์— dispose๋ฅผ ํ˜ธ์ถœํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค๊ณ  ํ–ˆ๋‹ค.
ํ•˜์ง€๋งŒ ๋งŒ์•ฝ ๋‹ค์Œ๊ณผ ๊ฐ™์ด, ํ•ด์ œํ•ด์ค˜์•ผ ํ•˜๋Š” ๋ฆฌ์†Œ์Šค๊ฐ€ ๋งŽ์•„์ง„๋‹ค๋ฉด,
class HjViewController: UIViewController { private var timerDisposable: Disposable? private var button1Disposable: Disposable? private var button2Disposable: Disposable? ... deinit { timerDisposable?.dispose() button1Disposable?.dispose() button2Disposable?.dispose() } }
Swift
๋ณต์‚ฌ
์ด๋ ‡๊ฒŒ ์ง€์ €๋ถ„ํ•ด์งˆ๊ฒƒ์ด๋‹ค.
๊ทธ๋ž˜์„œ Disposable๋“ค์„ ๋‹ด๋Š” ๋ฐฐ์—ด์„ ๋งŒ๋“ ๋‹ค โ†’ DisposableBag
public final class DisposeBag: DisposeBase { private var disposables = [Disposable]()
Swift
๋ณต์‚ฌ
RxSwift์—์„œ ์ œ๊ณตํ•˜๋Š” ์ด DisposeBag ์ด๋ž€ ๊ฒƒ์€ ์‰ฝ๊ฒŒ ๋งํ•ด์„œ Disposable ๊ฐ์ฒด๋ฅผ ๋‹ด๋Š” ๋ฐฐ์—ด์ด๋‹ค.
class HjViewController: UIViewController { private var disposeBag: DisposeBag = .init() }
Swift
๋ณต์‚ฌ
์œ„์ฒ˜๋Ÿผ, ์ „์—ญ ๋ณ€์ˆ˜๋กœ disposeBag ํ•˜๋‚˜๋ฅผ ์„ ์–ธํ•ด์ฃผ๊ณ , disposable ๊ฐ์ฒด๋ฅผ ์ด์ œ ์–ด๋–ป๊ฒŒ ๋‹ด๋ƒ๋ฉด,
extension Disposable { public func disposed(by bag: DisposeBag) { bag.insert(self) }
Swift
๋ณต์‚ฌ
Disposable ํ”„๋กœํ† ์ฝœ์˜ ๊ธฐ๋ณธ ๋ฉ”์„œ๋“œ๋กœ ์ œ๊ณตํ•˜๋Š” ์ด disposed(by bag: DisposeBag) ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ ๋‹ด์„ ๊ฒƒ์ด๋‹ค.
class HjViewController: UIViewController { private var disposeBag: DisposeBag = .init() override func viewDidLaod() { super.viewDidLoad() Observable<Int>.interval( .seconds(1), scheduler: MainScheduler.instance ) .subscribe(onNext: { print($0) }) .disposed(by: disposeBag) } }
Swift
๋ณต์‚ฌ
์œ„์ฒ˜๋Ÿผ, subscribe๋ฅผ ํ†ตํ•ด ๋ฐฐ์ถœ๋œ Disposable ๊ฐ์ฒด์— ๋Œ€๊ณ  disposed(by bag:) ๋ฉ”์„œ๋“œ๋กœ ๋ฏธ๋ฆฌ ์„ ์–ธ๋œ disposeBag ๊ฐ์ฒด๋ฅผ ๋„˜๊ฒจ์ฃผ๋ฉด, ํ•ด๋‹น disposeBag ์•ˆ์— ํ•ด๋‹น Disposable์ด ๋‹ด๊ธฐ๊ฒŒ ๋œ๋‹ค.
๊ทธ๋Ÿฌ๋ฉด, deinit ๋˜์–ด์•ผ ํ•  ๋•Œ, disposeBag ์•ˆ์— ๋“ค์–ด์žˆ๋Š” Disposable ๊ฐ์ฒด๋“ค์„ ๋‹ค dispose() ์‹œ์ผœ์•ผํ•˜๋‚˜?
๊ทผ๋ฐ, ๊ตณ์ด deinit ๋•Œ ์•„๋ฌด๋Ÿฐ ์ž‘์—…์„ ํ•ด์ฃผ์ง€ ์•Š์•„๋„ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.
public final class DisposeBag: DisposeBase { deinit { self.dispose() }
Swift
๋ณต์‚ฌ
์œ„์ฒ˜๋Ÿผ, DisposeBag ๊ฐ์ฒด ์ž์ฒด๊ฐ€ deinit ๋˜๋Š” ์ˆœ๊ฐ„, ๋‚ด๋ถ€์— ์žˆ๋Š” dispose() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
private func dispose() { let oldDisposables = self._dispose() for disposable in oldDisposables { disposable.dispose() } }
Swift
๋ณต์‚ฌ
์ด ๋ฉ”์„œ๋“œ์—์„œ ํ•ด๋‹น Disposables๋ž€ Disposable ๋ฐฐ์—ด์— ๋‹ด๊ธด disposable์„ ์ˆœํšŒํ•˜๋ฉด์„œ ๋ชจ๋‘ dispose() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
ย ์š”์•ฝ
DisposeBag์„ ์ „์—ญ ํ”„๋กœํผํ‹ฐ๋กœ ์„ ์–ธํ•ด์ค€ ๊ฒฝ์šฐ,
(๋‹ค๋ฅธ ๊ณณ์—์„œ ์ฐธ์กฐํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ) ํ•ด๋‹น DisposeBag์„ ๋‹ด๊ณ  ์žˆ๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ์‚ฌ๋ผ์งˆ ๋•Œ, DisposeBag์ด๋ž€ ํ”„๋กœํผํ‹ฐ๋„ ๊ฐ’์ด deinit์ด ๋  ๊ฒƒ์ด๊ณ ,
์ด๋•Œ ๋‚ด๊ฐ€ ๊ฐ–๊ณ  ์žˆ๋Š” Disposable์˜ ๋ฐฐ์—ด์„ ์ˆœํšŒํ•˜๋ฉฐ dispose() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์—,
๋”ฑํžˆ ๋ณ„๋„์˜ ์ž‘์—…์„ ํ•ด์ฃผ์ง€ ์•Š์•„๋„,
DisposeBag์ด ๊ฐ–๊ณ  ์žˆ๋Š” Disposable๋“ค์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋‚˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋˜ ๊ฒƒ์ด๋‹ค.
โ†’ ๋งŒ์•ฝ ํŠน์ • ์ˆœ๊ฐ„์— disposeBag์„ ์ง์ ‘ ๋น„์›Œ์ฃผ์–ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ด๋ผ๋ฉด ํ•ด๋‹น ์ƒํ™ฉ์— ๋งž๊ฒŒ disposeBag์„ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œํ•ด์ฃผ๋ฉด ๋œ๋‹ค.
disposeBag์€ ์ž์‹ ์ด deinit ๋  ๋•Œ,
์ž์‹ ์ด ๊ฐ€์ง€๊ณ  ์žˆ๋˜ ํ•ด๋‹น Disposable์„ ๋ชจ๋‘ dispose() ์‹œ์ผœ๋ฒ„๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์—,
class HjViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let disposeBag: DisposeBag = .init() Observable<Int>.interval( .seconds(1) scheduler: MainScheduler.instance ) .subscribe(onNext: { print($0) }) .disposed(by: disposeBag) } }
Swift
๋ณต์‚ฌ
์œ„์ฒ˜๋Ÿผ, ๋งŒ์•ฝ disposeBag์„ ์ „์—ญ์ด ์•„๋‹Œ viewDidLoad ๋ฉ”์„œ๋“œ ์•ˆ์˜ ์ง€์—ญ๋ณ€์ˆ˜๋กœ ์„ ์–ธํ•  ๊ฒฝ์šฐ,
viewDidLoad ๋ฉ”์„œ๋“œ๊ฐ€ ๋๋‚  ๋•Œ disposeBag๋„ ๊ฐ™์ด ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œ๋˜๊ธฐ ๋•Œ๋ฌธ์—,
์ด๋•Œ ๋“ฑ๋ก ๋˜์–ด ์žˆ๋Š” Observable ๋˜ํ•œ ๋‹ค ๊ฐ™์ด ๊ตฌ๋… ํ•ด์ œ ๋˜์–ด ๋ฒ„๋ ค ์œ„ ์ฝ”๋“œ์—์„œ์˜ Observable์ด ์ž‘๋™ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค.
๋”ฐ๋ผ์„œ, disposeBag์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์œ ์˜ํ•ด์•ผํ•œ๋‹ค โ†’ ๋ณดํ†ต ์ „์—ญ์— ๋‘”๋‹ค.

ย Subscribe ํ•  ๋•Œ ๋งˆ์ง€๋ง‰ ํด๋กœ์ € onDisposed:

public func subscribe( onNext: ((Element) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil ) -> Disposable
Swift
๋ณต์‚ฌ
ํ•ด๋‹น Observable์ด ๊ตฌ๋… ํ•ด์ œ๋  ๋•Œใ…ก
์ฆ‰, disposed() ๋ฉ”์„œ๋“œ๊ฐ€ ๋ถˆ๋ฆด ๋•Œ ์‹คํ–‰ ๋  ํด๋กœ์ €๋ฅผ ๋„˜๊ฒจ์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.
โ†’ onError๋‚˜ onComplete์œผ๋กœ ์ธํ•ด disposed ๋  ๋•Œ๋„ ๋‹น์—ฐํžˆ ์‹คํ–‰๋œ๋‹ค.
โ†’ ํ•ด๋‹น Observable์ด ๊ตฌ๋… ํ•ด์ œ ๋  ๋•Œ, ๋“ฑ๋กํ•ด๋†“์€ ํด๋กœ์ €๊ฐ€ ์‹คํ–‰๋œ๋‹ค.

ย Reference

RxSwift) Dispose /Disposable / DisposeBag ์ดํ•ดํ•˜๊ธฐ
์•ˆ๋…•ํ•˜์„ธ์š”, ์†Œ๋“ค์ž…๋‹ˆ๋‹ค XD hm.. ์š”์ฆ˜ ์ œ ๋ธ”๋กœ๊ทธ ๋Œ“๊ธ€์˜ ๋Œ€๋ถ€๋ถ„์ด ์†Œ๋“ค๋‹˜์€ ๊ฐœ๋ฐœ ๊ณต๋ถ€๋ฅผ ์–ด๋–ป๊ฒŒ ํ•˜์…จ๋‚˜์š”? ์— ๋Œ€ํ•œ ๋‚ด์šฉ์ธ๋“ฏ ํ•œ๋””.. ๊ต๊ณผ์„œ.. ์œ„์ฃผ๋กœ.. ๊ณต๋ถ€ํ•˜์…ˆ.. ๋‘๋ฒˆํ•˜์…ˆ.. ๋ผ๊ณ  ํ• ๋ป”... ใ…Žใ…Ž ๋‚˜์ค‘์— ์ œ ๊ณต๋ถ€ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ๋„ ํ•œ๋ฒˆ ํฌ์ŠคํŒ…์„ ํ•ด๋ณผ๊ฒŒ์šฅ!! ์ €๋ฒˆ ํฌ์ŠคํŒ…์—์„œ Observable๊ณผ Observer๊ฐ€ ๋ฌด์—‡์ด๊ณ  Subscribe๊ฐ€ ๋ฌด์—‡์ธ์ง€์— ๋Œ€ํ•ด์„œ ๊ณต๋ถ€๋ฅผ ํ•ด๋ดค์ž–์•„์š”??!! ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„  Dispose์— ๋Œ€ํ•ด ๊ณต๋ถ€ํ•ด๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹น!! ๋ชจ๋“  ํฌ์ŠคํŒ…์€ ํŽธ์˜ ๋งํˆฌ๋กœ ํ•ฉ๋‹ˆ๋‹ค~!! 1. Disposable๊ณผ dispose() ์—ฌ๋Ÿฌ๋ถ„ Dispose๋ผ๋Š” ๋‹จ์–ด์˜ ๋œป์„ ์•„์…ˆ?? Dispose๋Š” "์ฒ˜๋ฆฌํ•˜๋‹ค/์—†์• ๋‹ค"๋ผ๋Š” ๋œป์„ ๊ฐ–๊ณ  ์žˆ์Œ!! ๊ทธ๋Ÿผ ๋ฉ€ ์ฒ˜๋ฆฌํ•˜๋‚˜์—ผ..?? ์ž, ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ํ˜•ํƒœ Observable์ด ์žˆ..