๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐ŸŽ iOS

[RxSwift] DisposeBag ๊ณผ Operator

by ํ‹ด๋”” 2022. 1. 6.
728x90
๋ฐ˜์‘ํ˜•

observable์€ subscription๋˜๊ธฐ ์ „๊นŒ์ง€ ์•„๋ฌด๋Ÿฐ ์ด๋ฒคํŠธ๋„ ๋ฐฉ์ถœํ•  ์ˆ˜ ์—†๋‹ค -> ์•„๋ฌด๊ฒƒ๋„ ํ•  ์ˆ˜ ์—†์Œ

subscription์ด ์˜ต์ €๋ฒ„๋ธ”์ด ๋™์ž‘ํ•˜๋„๋ก ์ƒˆ๋กœ์šด ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœํ•˜๋„๋ก ํ•˜๊ณ  .error ํ˜น์€ .completed ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœํ•˜๊ฒŒ ํ•˜๋ฉฐ ์ข…๋ฃŒ์‹œํ‚ค๊ฒŒ ํ•˜๋Š” ํŠธ๋ฆฌ๊ฑฐ ๊ฐ™์€ ์—ญํ™œ์„ ํ•˜๋Š” ๊ฒƒ!

๊ทธ๋ ‡๋‹ค๋ฉด ๋”์ด์ƒ ์˜ต์ €๋ฒ„๋ธ”์ด ํ•„์š” ์—†์–ด์ง€๊ฑฐ๋‚˜ ๋” ์ด์ƒ ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœํ•˜๊ณ  ์‹ถ์ง€ ์•Š๋‹ค! ํ•  ๋•Œ๋Š” ์œ ํŠœ๋ธŒ ์ฒ˜๋Ÿผ ๊ตฌ๋… ์ทจ์†Œ ํ•  ์ˆ˜ ์žˆ์Œ

์ด๊ฑธ ์ˆ˜ํ–‰ ํ•˜๋Š” ๊ฒƒ์ด Disposing์˜ ๊ฐœ๋…์ด๊ณ  observable์€ ์ฆ‰์‹œ ์ข…๋ฃŒ๋œ๋‹ค!

 

$0์„ default argument๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ๊ฑธ ์ฒ˜์Œ ์•Œ์•˜๋‹น. ์ฑ…์—์„œ์˜ ํ‘œํ˜„์ธ๊ฐ€?

 

let disposeBag = DisposeBag()

์ด๋ ‡๊ฒŒ DisposeBag์„ ์ƒ์„ฑํ•˜์—ฌ ํ•œ๋ฒˆ์— ๊ด€๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค

observable์„ ๊ตฌ๋…ํ•˜๋Š” subscribe๋Š” ๋ฆฌํ„ด์œผ๋กœ Disposable์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. DisposeBag์€ ์ด๋Ÿฌํ•œ Disposable์„ ๋‹ด์•„ ํ• ๋‹นํ•ด์ œ์‹œ ๊ฐ๊ฐ์— ๋Œ€ํ•ด dispose() ๋ฅผ ํ˜ธ์ถœ ํ•  ์ˆ˜ ์žˆ์Œ

 

์™œ dispose๋ฅผ ํ•ด์ค˜์•ผ ํ•˜๋ƒ๋ฉด ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ์ผ์–ด๋‚  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค ์•„์ง ๋งŽ์ด ๋ฐฐ์šฐ์ง€ ์•Š์•„์„œ ์ž˜ ๋ชจ๋ฅด๊ฒ ๋Š”๋ฐ ์•„๋งˆ๋„ ์ด๊ฑธ ๋‹ค๋ฅธ ๊ณณ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‚˜๋ณด๋‹ค ๊ทธ๋ž˜์„œ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ง€ํ•˜๊ณ  ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์„ ๊ฐœ๋ฐœ์ž์—๊ฒŒ dispose๋กœ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ ๊ฐ™์€๋ฐ ๋‹คํ–‰ํžˆ swift compiler๊ฐ€ ์–ด๋Š์ •๋„ ์•Œ๋ ค์ค€๋‹ค๊ณ  ํ•œ๋‹ค!

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ์ผ์–ด๋‚  ์ˆ˜ ์žˆ๋Š” ์ƒํ™ฉ์€

DisposeBag์—๋‹ค๊ฐ€ subscribe๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์„ ์žŠ์—ˆ์„ ๊ฒฝ์šฐ

subscribe๋ฅผ ๋งˆ์นœ ํ›„ ์ˆ˜๋™์œผ๋กœ ์‚ญ์ œ๋ฅผ ํ˜ธ์ถœ <- ์ด๊ฑด ๋ฌด์Šจ ๋œป์ผ๊นŒ..

๋‹ค๋ฅธ point์—์„œ observable์ด ์ข…๋ฃŒ๋˜๋Š” ๊ฒฝ์šฐ

 

์˜คํผ๋ ˆ์ดํ„ฐ ๊ณต๋ถ€ํ•˜๋Š”๋ฐ ๋„์›€์„ ์ฃผ๋Š” ์‚ฌ์ดํŠธ

https://reactivex.io/documentation/operators.html

 

ReactiveX - Operators

Introduction Each language-specific implementation of ReactiveX implements a set of operators. Although there is much overlap between implementations, there are also some operators that are only implemented in certain implementations. Also, each implementa

reactivex.io

 

create ์˜คํผ๋ ˆ์ดํ„ฐ 

Observable์„ ์ƒ์„ฑํ•˜๋Š” Operator

๋‹ค๋ฅธ ๊ฒƒ๊ณผ ๋‹ฌ๋ฆฌ ์ง์ ‘์ ์ธ ์ฝ”๋“œ ๊ตฌํ˜„์„ ํ†ตํ•ด ์˜ต์ €๋ฒ„๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค   subscribers์—๊ฒŒ ์ „์†ก๋  ๋ชจ๋“  '์ด๋ฒคํŠธ'๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

subscribe ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ Observable์„ ์ƒ์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์— subscriber ์—†์ด๋Š” ์–ด๋– ํ•œ ์ด๋ฒคํŠธ๋„ ๋ฐฉ์ถœ๋˜์ง€ ์•Š๋Š”๋‹ค! disposable์„ ์ง์ ‘ ๋ฆฌํ„ดํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค!

 

 Observable<String>.create { observer in
            // subscriber๊ฐ€ ๋ฐฉ์ถœํ•  ์ด๋ฒคํŠธ๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Œ
            observer.onNext("cat")
            observer.onError(CustomError.testError)
            observer.onCompleted()
            observer.onNext("dog")
            return Disposables.create()
        }
        .subscribe { event in
            print(event)
        } onError: { error in
            print(error)
        } onCompleted: {
            print("create observable, Completed")
        } onDisposed: {
            print("create observable, Disposed")
        }.disposed(by: disposeBag)
        enum CustomError: Error {
            case testError
        }

create์˜คํผ๋ ˆ์ดํ„ฐ์—์„œ  subscribe ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ์ธ์ž๋กœ ๋„˜๊ฒจ์ค€  subscribe ์—์„œ ์ง์ ‘์ ์œผ๋กœ ์ฝ”๋“œ ๊ตฌํ˜„์„ ํ•  ์ˆ˜ ์žˆ์Œ (์˜ต์ €๋ฒ„๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„˜๊ฒจ์ฃผ๋Š” ๊ฒƒ)

์ด๋ฅผ ํ†ตํ•ด์„œ ์˜ต์ €๋ฒ„ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๋Š”๋ฐ ๊ฒฐ๊ณผ ๊ฐ’์€ ๊ทธ๋ž˜์„œ ์˜ต์ €๋ฒ„๋ธ”! ์ƒ์„ฑ๋œ ๊ฐ’์€ ์˜ต์ €๋ฒ„๋ธ” ์‹œํ€€์Šค์ด๋‹ค

์œ„์— ์ฝ”๋“œ์—์„œ terminate ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœํ•˜๋Š” ๊ฑธ ์•Œ ์ˆ˜ ์žˆ๋Š”๋ฐ error์„ ํ˜ธ์ถœํ•˜๊ณ   completed ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๊ฒฐ๊ณผ๋Š” .completed ์ด๋ฒคํŠธ๋Š” ๋ฐฉ์ถœ๋˜์ง€ ์•Š๋Š”๋ฐ .error ์ด๋ฒคํŠธ ๋ฐฉ์ถœ๋œ ํ›„ ๋ฐ”๋กœ terminated ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค! 

๋งŒ์•ฝ terminate์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœํ•˜์ง€ ์•Š์œผ๋ฉด ์ ˆ๋Œ€ dispose ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ completed ์ด๋ฒคํŠธ๋‚˜ disposeBag์„ ์ถ”๊ฐ€ํ•ด ์ฃผ๋ฉด ๋œ๋‹ค

 

 

Observable ์ •์˜ ํ›„ ๋‹ค๋ฅธ ๊ณณ์—์„œ subscribe ํ•˜๋ฉด ๋‚ด๊ฐ€ create์—์„œ ์ •์˜ํ•œ ์ด๋ฒคํŠธ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ๋ฐฉ์ถœ ์‹œํ‚ฌ ์ˆ˜ ์žˆ๊ณ  terminate ์‹œํ‚ฌ ์ˆ˜๋„ ์žˆ๋Š” ๊ฒƒ! ๊ต‰์žฅํžˆ ์ข‹์€ ๊ธฐ๋Šฅ์ด๋‹ค! ์™œ ๊ธฐ์กด ํ”„๋กœ์ ํŠธ ์ƒ์„ฑํ•  ํ•„์š” ์—†์ด ๋ฆฌํŒฉํ† ๋ง ํ•ด๋„ ๋œ๋‹ค ํ•œ์ง€ ์•Œ๊ฒƒ ๊ฐ™๋‹ค. ์ ์ ˆํ•œ ๊ณณ์—๋‹ค๊ฐ€ rx๋กœ ๋กœ์ง ์ถฉ๋ถ„ํžˆ ์งค ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค

 

Observable Factories

ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์›ํ•˜๋Š” ๋งŒํผ์˜ ๋งŽ์€ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค Rx์—์„œ ํŒฉํ† ๋ฆฌ๋Š” ์ธํ’‹์„ ์˜ต์ €๋ฒ„๋ธ”๋กœ ๋ณ€ํ™˜์‹œ์ผœ ์ฃผ๊ธฐ ๋•Œ๋ฌธ์— Operator๋กœ ๊ฐ„์ฃผ๋œ๋‹ค

RxSwift์—์„œ ์ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์˜คํผ๋ ˆ์ดํ„ฐ๋Š” differ ๋กœ ๊ตฌํ˜„๋˜๋Š”๋ฐ ์ธํ’‹๊ณผ ์•„์›ƒํ’‹์ด ๊ธฐ์กด์— ๋ดค๋˜ ์˜คํผ๋ ˆ์ดํ„ฐ์™€ ์ข€ ๋‹ค๋ฅด๋‹ค

๋ฐ˜ํ™˜๊ฐ’์„ ๋ณด๋ฉด observable์ด๋‹ค ์ฆ‰ ์˜ต์ €๋ฒ„๋ธ”์„ ์ƒ์„ฑํ•˜๋Š”๋ฐ ์ง์ ‘ ์˜ต์ €๋ฒ„๋ธ”์„ ๋ฐ˜ํ™˜ํ•ด ์ค€๋‹ค๋Š” ๊ฒƒ

ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ๋Š” observableFactory๋ฅผ ์ง€์ •ํ•ด ์ฃผ์–ด์•ผ ํ•˜๋Š”๋ฐ Observable ํŒฉํ† ๋ฆฌ

 

๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด์ง„ Observable์„ ๊ตฌ๋…ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ๊ตฌ๋… ์‹œ์ ์—์•ผ Observable์„ ๋งŒ๋“ฌ

์ „ํ˜•์ ์ธ ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜๋ž€ --> subscribe ๋˜๊ธฐ ์ „๊นŒ์ง€ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ ๊ตฌ๋…์ด ๋˜๋ฉด  Observable ์ƒ์„ฑ 

์ถœ์ฒ˜ : ReactiveX

์ด deferred ์˜คํผ๋ ˆ์ดํ„ฐ๋กœ ์ƒ์„ฑ๋œ Observable์„ ๊ตฌ๋…ํ•˜๋Š” subscribe ๋งˆ๋‹ค deferred์˜ observableFatory๋กœ ์ „๋‹ฌํ•œ ๊ฒƒ์ด ์ƒˆ๋กญ๊ฒŒ ์‹คํ–‰๋˜๋Š” ๊ฒƒ, ์ฆ‰ ์—ฌ๋Ÿฌ ๊ตฌ๋…์ž๊ฐ€ ๋™์ผํ•œ Observable์— ๊ฐ€์ž…ํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐ๋  ์ˆ˜ ์žˆ์œผ๋‚˜ ์‚ฌ์‹ค์€ ๊ฐœ๋ณ„ ์‹œํ€€์Šค๋ฅผ ๊ฐ€์ง ( โญ๏ธโญ๏ธโญ๏ธโญ๏ธโญ๏ธ)

๊ทธ๋ฆผ์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด ๊ฐ subscribe ๋ณ„๋กœ ๋‹ค๋ฅธ ์‹œํ€€์Šค๋ฅผ ๊ฐ€์ง„๋‹ค! ํ•˜๋‚˜์˜ Observable์„ ๊ฐ€์ง€๊ณ  ๋˜‘๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ์ฐ๋Š” ๊ฒƒ์ด ์•„๋‹Œ ๊ฐœ๋ณ„ ์‹œํ€€์Šค!!

 

์ด์ฏค์—์„œ ์‹œํ€€์Šค๋ž‘ Observable์ด ๋งค์šฐ ํ—ท๊ฐˆ๋ฆฌ๋Š”๋ฐ Observable์€ ์ผ๋ จ์˜ Sequence(์ˆœ์„œ)๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ  ์ด ์ˆœ์„œ๋Œ€๋กœ ๊ตฌ๋…ํ•œ ๋Œ€์ƒ์—๊ฒŒ ์ด๋ฒคํŠธ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ

everything is sequence!

๊ด€์ฐฐ์ž ํŒจํ„ด์ธ Observable<Element> ์‹œํ€€์Šค์™€ ์ผ๋ฐ˜์ ์ธ ์‹œํ€€์Šค์˜ ๊ฐœ๋…์ด ๊ฐ™์Œ

Observable์€ ์ผ๋ จ์˜ ์ˆœ์„œ๋Œ€๋กœ ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœํ•˜๊ฒŒ ๋˜๋Š”๋ฐ ๊ทธ๋ ‡๊ธฐ์— Observable์ด  sequence์™€ ๊ฐ™์€ ๊ฐœ๋…์œผ๋กœ ์“ฐ์ผ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ž„

        let disposeBag = DisposeBag()
        var hasNewImageUpdated = false
        let factory: Observable<String> = Observable.deferred {
            hasNewImageUpdated.toggle()
            
            if hasNewImageUpdated {
                return Observable.of("image1.jpg", "image2.jpg")
            } else {
                return Observable.of("newUpdatedImage.jpg")
            }
        }
        
        for _ in 0...3 {
            factory.subscribe(onNext: { element in
                print(element, terminator: ", ")
            }).disposed(by: disposeBag)
            print()
        }

 

๋ฌธ์ œ์‹œ ๋Œ“๊ธ€๋กœ ์•Œ๋ ค์ฃผ์„ธ์š”!!

 

 

์ฐธ๊ณ  ์‚ฌ์ดํŠธ ๋ฐ ๋„์„œ : 

https://medium.com/tompee/rxjava-ninja-observable-factories-part-1-98c97f6db853

 

728x90
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€