๐ŸŽ iOS & Swift

[RxSwift] Disposable๊ณผ DisposeBag

taeeekki 2022. 10. 26. 04:23

๋“ค์–ด๊ฐ€๋ฉฐ

๊ธฐ๋ก์˜ ์†Œ์ค‘ํ•จ์„ ์•Œ๋ฉด์„œ๋„ ๋ฌด์–ธ๊ฐ€๋ฅผ ๊พธ์ค€ํžˆ ๊ธฐ๋กํ•œ๋‹ค๋Š” ๊ฒƒ์€ ์ฐธ ์–ด๋ ค์šด ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ์ €๋Ÿฐ ์ƒ๊ฐ์„ ๋งŽ์ด ํ–ˆ์ง€๋งŒ ๊ทธ๋ƒฅ ํ•‘๊ณ„๋Œ€์ง€๋ง๊ณ , ๋ช‡ ์ž๋ผ๋„ ๋‚จ๊ฒจ๋†“๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค๋Š” ๊ฒฐ๋ก ์„ ๋‚ด๋ ธ์Šต๋‹ˆ๋‹ค. ๊นŠ์ด ์žˆ๋Š” ๊ธ€์€ ๋‹ฌ์— 1~2๋ฒˆ ์ •๋„ ์ ๋Š” ๊ฒƒ์œผ๋กœ ํ•˜๊ณ  ์šฐ์„ ์€ ๊พธ์ค€ํžˆ ๋ฉ”๋ชจ(ex. ํ‚ค์›Œ๋“œ, ์š”์•ฝ ๋“ฑ)๋ฅผ ํ•˜๋Š” ์‹์œผ๋กœ ๊ฐ€๋ณด๋ ค๊ณ  ํ•ด์š”. ๊นƒํ—ˆ๋ธŒ์— ๊ธฐ๋กํ•˜๋Š” ๊ฒƒ์ด ํŽธํ•ด์„œ ๋ณดํ†ต ๋ฉ”๋ชจ๋‚˜ ๊ธฐ๋ก์„ ๊นƒํ—ˆ๋ธŒ์— ํ•˜๋Š” ํŽธ์ด์ง€๋งŒ, ์•ž์œผ๋กœ ๋ธ”๋กœ๊ทธ์—๋„ ๋™์‹œ์— ๊พธ์ค€ํžˆ ํฌ์ŠคํŒ…ํ•  ์ƒ๊ฐ์ž…๋‹ˆ๋‹ค. ํŒŒ์ดํŒ…!!

 

Disposable

RxSwift > Disposable
//  Disposable.swift

/// Represents a disposable resource.
public protocol Disposable {
    /// Dispose resource.
    func dispose()
}
  • '์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š”'์˜ ์‚ฌ์ „์  ์˜๋ฏธ๋ฅผ ์ง€๋‹™๋‹ˆ๋‹ค.
  • protocol ํƒ€์ž…์ž…๋‹ˆ๋‹ค.
  • dispose() ๋ฉ”์„œ๋“œ๊ฐ€ ์„ ์–ธ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

//  ObservableType+Extensions.swift

public func subscribe( 
    onNext: ((Element) -> Void)? = nil,
    onError: ((Swift.Error) -> Void)? = nil,
    onCompleted: (() -> Void)? = nil,
    onDisposed: (() -> Void)? = nil
) -> Disposable { ... }
  • Observable์€ subscribe(๊ตฌ๋…)์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  • ๋ชจ๋“  subscription ๊ฐ์ฒด๋Š” Disposable ํ•ฉ๋‹ˆ๋‹ค.
  • Disposable ํ•˜๋‹ค๋Š” ๊ฒƒ์˜ ํ•ต์‹ฌ์€ dispose๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

๐Ÿ“Œ ํ•ต์‹ฌ์€ Disposableํ•œ ๊ฐ์ฒด๋Š” dispose๋ฅผ ์ˆ˜ํ–‰ํ•จ์œผ๋กœ์จ '๋ฆฌ์†Œ์Šค ์ •๋ฆฌ'์™€ '๊ตฌ๋… ์ทจ์†Œ'๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

DisposeBag

// 1. ์˜ต์ €๋ฒ„๋ธ”(์ด๋ฒคํŠธ ๋ฐฉ์ถœ)
let observable = Observable.just("RxSwift")

// 2. ๊ตฌ๋…์ž(๊ตฌ๋…ํ•˜๋Š” ์‹œ์ ๋ถ€ํ„ฐ ์˜ต์ €๋ฒ„๋ธ”์ด ๋ฐฉ์ถœํ•˜๋Š” ์š”์†Œ๋ฅผ ๋ฐ›์•„๋ณผ ์ˆ˜ ์žˆ์Œ)
let subsriber1 = observable
    .subscribe(onNext: { element in
        print(element)
    })

let subsriber2 = observable
    .subscribe(onNext: { element in
        print(element)
    })

// 3. ๊ตฌ๋… ์ทจ์†Œ
subsriber1.dispose()
subsriber2.dispose()

์šฐ๋ฆฌ๋Š” ์‹œํ€€์Šค๋ฅผ ๊ฐ๊ฐ dispose ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๊ตฌ๋… ์ทจ์†Œ ํ•ด์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋”ฐ๋กœ๋”ฐ๋กœ ๊ตฌ๋… ์ทจ์†Œ๋ฅผ ํ•˜๋Š” ๊ฒƒ์€ ๋ฒˆ๊ฑฐ๋กญ๊ธฐ๋„ ํ•˜๊ณ , ์‹œํ€€์Šค๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ๊ฐ€ ์žˆ์„ ๋•Œ๋Š” ๊ตฌ๋… ์ทจ์†Œ ํ•˜๋Š” ๊ฒƒ์„ ๋†“์น  ์ˆ˜๋„ ์žˆ์ฃ . ๊ทธ๋ ‡๊ธฐ์— RxSwift์—์„œ ์ข€ ๋” ํŽธํ•œ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

DisposeBag

๋ฐ”๋กœ Disposableํ•œ ๊ฒƒ์„ ๋‹ด์„ ์ˆ˜ ์žˆ๋Š” ๊ฐ€๋ฐฉ(Bag)์„ ์ œ๊ณตํ•˜๋Š”๋ฐ์š”. ์šฐ๋ฆฌ๊ฐ€ ์‹œํ€€์Šค๋ฅผ ์ผ์ผ์ด ๊ตฌ๋… ์ทจ์†Œ ํ•˜๋Š” ๊ฒƒ์„ ๋†“์น  ์ˆ˜ ์žˆ์œผ๋‹ˆ๊นŒ '๊ทธ๋ƒฅ DisposeBag์— ๋ชจ์•„์„œ ๋‹ด์•„๋†”, ๊ทธ๋Ÿฌ๋ฉด ์šฐ๋ฆฌ๊ฐ€ ์•Œ์•„์„œ dispose ํ•ด์ค„๊ฒŒ!' ์ด๋Ÿฐ ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.

let disposeBag = DisposeBag()
  • ๋‹ค์Œ๊ณผ ๊ฐ™์ด DisposeBag ๊ฐ์ฒด๋ฅผ ์ „์—ญ ๋ณ€์ˆ˜๋กœ ๋งŒ๋“ค์–ด๋†“๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ด€๋ก€์ ์œผ๋กœ disposeBag ๋ณ€์ˆ˜๋ช…์„ ์“ฐ๋Š” ๊ฒƒ ๊ฐ™์•„์š”.
// 1. ์˜ต์ €๋ฒ„๋ธ”(์ด๋ฒคํŠธ ๋ฐฉ์ถœ)
let observable = Observable.just("RxSwift")

// 2. ๊ตฌ๋…์ž(๊ตฌ๋…ํ•˜๋Š” ์‹œ์ ๋ถ€ํ„ฐ ์˜ต์ €๋ฒ„๋ธ”์ด ๋ฐฉ์ถœํ•˜๋Š” ์š”์†Œ๋ฅผ ๋ฐ›์•„๋ณผ ์ˆ˜ ์žˆ์Œ)
let subsriber1 = observable
    .subscribe(onNext: { element in
        print(element)
    }).dispose(by: disposeBag)

let subsriber2 = observable
    .subscribe(onNext: { element in
        print(element)
    }).dispose(by: disposeBag)
  • ๊ฐ ์‹œํ€€์Šค์˜ ๋ง๋ฏธ๋ฅผ ๋ณด๋ฉด disposeBag์— ๋‹ด์•„๋†“์€ ๊ฒƒ์ด ๋ณด์ด์‹œ๋‚˜์š”.
  • subscriptionํ•œ ๊ฐ์ฒด๋“ค์„ ์ด๋ ‡๊ฒŒ disposeBag์— ๋‹ด์•„๋†“๊ฒ ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ

let disposeBag = DisposeBag()
  • ์ดํ›„์— ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ deinit ๋  ๋•Œ disposeBag ๊ฐ์ฒด๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œ๋˜๋ฉด์„œ ๊ทธ ์•ˆ์—์„œ ๊ด€๋ฆฌ๋˜๊ณ  ์žˆ๋˜ Disposableํ•œ ์š”์†Œ๋“ค ์—ญ์‹œ ํ•ด์ œ๊ฐ€ ๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  • ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ํ•  ์ผ ๋๋‚ฌ์œผ๋‹ˆ disposeBag๋ณด๊ณ  ๋– ๋‚˜๋ผ๊ณ  ํ•˜๋Š”๊ฑฐ์ฃ . ๊ทธ๋Ÿผ disposeBag๊ฐ€ ๋ฐ๋ฆฌ๊ณ  ์žˆ๋˜ ์ž์‹๋“ค๋„ ๊ฐ™์ด ๋– ๋‚  ์ˆ˜๋ฐ–์— ์—†๊ฒ ์ฃ ...?
var disposeBag: DisposeBag?
...
disposeBag = nil
  • nil์„ ๋„ฃ์–ด์ค˜์„œ ํ•ด์ œํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
var disposeBag = DisposeBag()
...
self.disposeBag = DisposeBag()
  • subscribe ์ค‘์ด๋˜ Disposables๋ฅผ ์ดˆ๊ธฐํ™”ํ•ด์ฃผ๊ณ  ์‹ถ์„ ๋•Œ ์ƒˆ๋กœ์šด DisposeBag ์ธ์Šคํ„ด์Šค๋ฅผ ๋„ฃ์–ด์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ธฐ์กด์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ํ•œ ๋ฒˆ์— ์ •๋ฆฌํ•ด์ค„ ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. disposeBag์ด ํ•ด์ œ๋˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ์›๋ฆฌ์ž…๋‹ˆ๋‹ค.