ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

๋ฐ˜์‘ํ˜•

๐ŸŽฏ RxSwift ์ดํ•ดํ•˜๊ธฐ_05


RxSwift ์ดํ•ดํ•˜๊ธฐ_01 - https://jayb-log.tistory.com/275

RxSwift ์ดํ•ดํ•˜๊ธฐ_02 - https://jayb-log.tistory.com/276

RxSwift ์ดํ•ดํ•˜๊ธฐ_03 - https://jayb-log.tistory.com/277

RxSwift ์ดํ•ดํ•˜๊ธฐ_04 - https://jayb-log.tistory.com/278


  • ๐Ÿ™‹ ์ด ๊ธ€์€ RxSwift์— ๋Œ€ํ•œ ์—„์ฒญ๋‚œ ์ดํ•ด๋‚˜ ๋ณธ์งˆ์„ ํŒŒ์•…ํ•œ๋‹ค๊ธฐ๋ณด๋‹ค ์ž…๋ฌธํ•˜๋Š” ์ž…์žฅ์—์„œ ์ž‘์„ฑํ•˜๋Š” ๊ธ€์ด์—์š”! ๊ณฐํŠ€๊น€๋‹˜์˜ ๊ฐ•์˜(ํ•˜๋‹จ์— ๋งํฌ) ๋ฅผ ๋“ค์œผ๋ฉฐ ์ •๋ฆฌํ•œ ๋‚ด์šฉ, ์ƒ๊ฐ๋“ค์„ ์ž‘์„ฑํ•  ์˜ˆ์ •์ด์—์š”. ํ‹€๋ฆฐ ๋ถ€๋ถ„์ด๋‚˜ ์ถ”๊ฐ€ํ•˜๋ฉด ์ข‹์€ ๋ถ€๋ถ„์— ๋Œ€ํ•œ ํ”ผ๋“œ๋ฐฑ์€ ์–ธ์ œ๋‚˜ ํ™˜์˜์ž…๋‹ˆ๋‹ค :]


  • ์ด ๊ธ€์—์„œ๋Š” Main Thread, Concurrency Thread์—์„œ ์ž‘์—…ํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ๋Šฅ๋“ค์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•ด๋ณผ๊ฒŒ์š” โ˜บ๏ธ


  • ์ด ๊ธ€์—์„œ ์“ฐ๋ ˆ๋“œ์— ๋Œ€ํ•œ ์„ค๋ช…์„ ํ•˜์ง€๋Š” ์•Š์„๊ฒŒ์š”! ํ˜น์‹œ ๋‘ ์“ฐ๋ ˆ๋“œ์˜ ์ฐจ์ด์— ๋Œ€ํ•ด ์„ค๋ช…ํ•˜๊ธฐ ์–ด๋ ค์šฐ์‹œ๋‹ค๋ฉด ์“ฐ๋ ˆ๋“œ์— ๋Œ€ํ•œ ํ•™์Šต์„ ์„ ํ–‰ํ•˜์‹œ๋Š” ๊ฑธ ์ถ”์ฒœ๋“œ๋ ค์š” :]


๐Ÿง‘๐Ÿปโ€๐Ÿ’ป observeOn


  • ์•ž์„œ ์‚ดํŽด๋ดค์—ˆ๋˜ ์˜ˆ์ œ๋ฅผ ๋‹ค์‹œ ํ•œ ๋ฒˆ ๋ณผ๊ฒŒ์š”.


    @IBAction func exMap3() {
            Observable.just("800x600")
                .map { $0.replacingOccurrences(of: "x", with: "/") }
                .map { "https://picsum.photos/\($0)/?random" }
                .map { URL(string: $0) }
                .filter { $0 != nil }
                .map { $0! }
                .map { try Data(contentsOf: $0) }
                .map { UIImage(data: $0) }
                .subscribe(onNext: { image in
                    self.imageView.image = image
                })
                .disposed(by: disposeBag)
        }

    ์œ„์˜ ์ฝ”๋“œ๋Š” Main Thread์—์„œ ๋™์ž‘ํ•˜๊ฒŒ๋˜์š”. ๋ชจ๋“  ์ž‘์—…๋“ค์ด Main์—์„œ ์ž‘์—…๋˜๊ธฐ ๋•Œ๋ฌธ์— Concurrency Thread๋กœ ์˜ฎ๊ฒจ์ค˜์•ผ ํ•ด์š”. ์ด๋ ‡๊ฒŒ ์“ฐ๋ ˆ๋“œ๋ฅผ ์ด๋™์‹œํ‚ฌ ๋•Œ observeOn์„ ์‚ฌ์šฉํ•ด์š”.


    @IBAction func exMap3() {
            Observable.just("800x600")
                          .observeOn(ConcurrentDispatchQueueScheduler(qos: .default)) // ์“ฐ๋ ˆ๋“œ ์ด๋™
                .map { $0.replacingOccurrences(of: "x", with: "/") }
                .map { "https://picsum.photos/\($0)/?random" }
                .map { URL(string: $0) }
                .filter { $0 != nil }
                .map { $0! }
                .map { try Data(contentsOf: $0) }
                .map { UIImage(data: $0) }
                .subscribe(onNext: { image in
                    self.imageView.image = image
                })
                .disposed(by: disposeBag)
        }

    ํ•˜์ง€๋งŒ ์œ„ ์ฒ˜๋Ÿผ๋งŒ ์ž‘์„ฑํ•˜๋ฉด ์ด๋ฏธ์ง€๋ฅผ Settingํ•˜๋Š” ์ž‘์—…์€ Main Thread์—์„œ ์ด๋ค„์ ธ์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ถ”๊ฐ€์ ์ธ ์ž‘์—…์ด ํ•„์š”ํ•ด์š”.


    @IBAction func exMap3() {
            Observable.just("800x600")
                        .observeOn(ConcurrentDispatchQueueScheduler(qos: .default)) // ์“ฐ๋ ˆ๋“œ ์ด๋™
                .map { $0.replacingOccurrences(of: "x", with: "/") }
                .map { "https://picsum.photos/\($0)/?random" }
                .map { URL(string: $0) }
                .filter { $0 != nil }
                .map { $0! }
                .map { try Data(contentsOf: $0) }
                .map { UIImage(data: $0) }
                          .observeOn()
                          .observeOn(MainScheduler.instance) // ์ด๋ฏธ์ง€ ์„ธํŒ… ์ง์ „ ์“ฐ๋ ˆ๋“œ ์žฌ์ด๋™
                .subscribe(onNext: { image in
                    self.imageView.image = image
                })
                .disposed(by: disposeBag)
        }

    observeOn์ด ๊ฑธ๋ ค์žˆ๋Š” ๋‹ค์Œ ์ค„๋ถ€ํ„ฐ์˜ Stream๋“ค์€ ๋ชจ๋‘ observeOn์— ๊ฑธ๋ ค์žˆ๋Š” ์“ฐ๋ ˆ๋“œ์—์„œ ๋™์ž‘ํ•˜๊ฒŒ ๋˜์š”. ์ฆ‰, observeOn์˜ ์œ„์น˜๋ฅผ ์กฐ์ •ํ•˜์—ฌ ํŠน์ • ์ž‘์—…๋งŒ concurrentํ•˜๊ฒŒ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์ฃ . ๋งŒ์•ฝ ์œ„์˜ ์ž‘์—…์„ ์กฐ๊ธˆ ๋ณ€๊ฒฝํ•ด์„œ


    @IBAction func exMap3() {
            Observable.just("800x600")
                .map { $0.replacingOccurrences(of: "x", with: "/") }
                .map { "https://picsum.photos/\($0)/?random" }
                .map { URL(string: $0) }
                .filter { $0 != nil }
                .map { $0! }
                .map { try Data(contentsOf: $0) }
                          .observeOn(ConcurrentDispatchQueueScheduler(qos: .default)) // ์“ฐ๋ ˆ๋“œ ์ด๋™
                .map { UIImage(data: $0) }
                          .observeOn()
                          .observeOn(MainScheduler.instance) // ์ด๋ฏธ์ง€ ์„ธํŒ… ์ง์ „ ์“ฐ๋ ˆ๋“œ ์žฌ์ด๋™
                .subscribe(onNext: { image in
                    self.imageView.image = image
                })
                .disposed(by: disposeBag)
        }

    ์ด๋ ‡๊ฒŒ ๋ฐฐ์น˜ํ•  ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๋Š” ๋™์•ˆ ์•ฑ์ด ๋ฉˆ์ถ”๊ฒŒ ๋ ๊ฑฐ์—์š”. Data๋ฅผ ๊ฐ€์ ธ์˜ค๋Š”๋ฐ ์‹œ๊ฐ„์ด ๋งŽ์ด ๊ฑธ๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ Main Thread์—์„œ ์ง„ํ–‰ํ•  ๊ฒฝ์šฐ ๋”œ๋ ˆ์ด๊ฐ€ ๋Š๊ปด์ง€๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด์ฃ .



๐Ÿง‘๐Ÿปโ€๐Ÿ’ป subscribeOn


  • observeOn์˜ ๊ฒฝ์šฐ observeOn์ด ์ •์˜๋œ ๊ทธ ๋‹ค์Œ ์ค„๋ถ€ํ„ฐ ์˜ํ–ฅ์„ ๋ผ์น˜๊ฒŒ ๋œ๋‹ค๊ณ  ํ–ˆ์—ˆ์ฃ ! subscribeOn์€ ์ด์™€ ๋‹ค๋ฅด๊ฒŒ ์ด๋ฆ„ ๊ทธ๋Œ€๋กœ subscribe๊ฐ€ ๋˜๋Š” ์‹œ์  ๋ถ€ํ„ฐ๋ฅผ ์˜๋ฏธํ•ด์š”.


    @IBAction func exMap3() {
            Observable.just("800x600")
                .map { $0.replacingOccurrences(of: "x", with: "/") }
                .map { "https://picsum.photos/\($0)/?random" }
                .map { URL(string: $0) }
                .filter { $0 != nil }
                .map { $0! }
                .map { try Data(contentsOf: $0) }
                          .subscribeOn(ConcurrentDispatchQueueScheduler(qos: .default)) // ์“ฐ๋ ˆ๋“œ ์ด๋™
                .map { UIImage(data: $0) }
                          .observeOn()
                          .observeOn(MainScheduler.instance) // ์ด๋ฏธ์ง€ ์„ธํŒ… ์ง์ „ ์“ฐ๋ ˆ๋“œ ์žฌ์ด๋™
                .subscribe(onNext: { image in
                    self.imageView.image = image
                })
                .disposed(by: disposeBag)
        }

    ์ฆ‰, subscribe๊ฐ€ ์‹œ์ž‘๋˜๋Š” ์‹œ์ ๋ถ€ํ„ฐ Concurrentํ•˜๊ฒŒ ์ž‘์—…์„ ์ง„ํ–‰ํ• ๊ฑฐ์•ผ! ๋ผ๋Š” ๋œป์ด ๋ฉ๋‹ˆ๋‹ค. ๋‹น์—ฐํžˆ subscribeOn์˜ ์œ„์น˜๋Š” ์ค‘์š”ํ•˜์ง€ ์•Š๊ฒ ์ฃ ? ์–ด๋””์— ์œ„์น˜ํ•˜๋”๋ผ๋„ ์‹œ์ž‘ ์‹œ์ ์ด subscribe๊ฐ€ ๋˜๋‹ˆ๊นŒ์š” :]

    ์œ„์˜ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด, subscribe ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰ ๋  ๋•Œ Observable๋ถ€ํ„ฐ ์ญ‰ Stream์ด ์ง„ํ–‰๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

    Scheduler๋Š” ์ด๊ฒƒ๋งŒ ์•Œ์•„๋„ ์ถฉ๋ถ„ํ•ด์š”! OperationQueue๋‚˜ GCD๋ฅผ ์ปค์Šคํ…€ํ•ด์„œ ์‚ฌ์šฉํ• ๊ฒŒ ์•„๋‹ˆ๋ผ๋ฉด


    Main Thread -> MainScheduler.instance

    Concurrency Thread -> ConcurrentDispatchQueueScheduler(qos: .default)


    ๋ฅผ ์ž˜ ํ™œ์šฉํ•˜๋„๋ก ํ•ด์š”!


๐Ÿ™Š Side Effect


  • ์˜ˆ์‹œ์ฝ”๋“œ๋ฅผ ๋˜ ๋‹ค์‹œ ๋ณผ๊ฒŒ์š”!


    @IBAction func exMap3() {
            Observable.just("800x600")
                .map { $0.replacingOccurrences(of: "x", with: "/") }
                .map { "https://picsum.photos/\($0)/?random" }
                .map { URL(string: $0) }
                .filter { $0 != nil }
                .map { $0! }
                .map { try Data(contentsOf: $0) }
                .map { UIImage(data: $0) }
                .subscribe(onNext: { image in
                    self.imageView.image = image
                })
                .disposed(by: disposeBag)
        }

    ์—ฌ๊ธฐ์„œ map ๋“ฑ์˜ stream์€ ๋ฉ”์†Œ๋“œ ๋‚ด๋ถ€์ ์œผ๋กœ๋งŒ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ๋ณ€์— ์˜ํ–ฅ์„ ๋ผ์น˜์ง€ ์•Š์ง€๋งŒ subscribe์˜ ๊ฒฝ์šฐ ๋ฉ”์†Œ๋“œ ์™ธ๋ถ€์˜ ํ”„๋กœํผํ‹ฐ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๊ณ  ์žˆ์–ด์š”.

    image๋ฅผ ๋ฐ›์•„์„œ ํ”„๋กœํผํ‹ฐ์— ํ• ๋‹นํ•˜๋Š” ๊ตฌ์กฐ๋‹ˆ๊นŒ์š”.

    ์ฆ‰, ๋ฉ”์†Œ๋“œ ์™ธ๋ถ€์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๊ณ  ์žˆ๋‹ค๊ณ  ํ•  ์ˆ˜ ์žˆ๊ณ  ์ด๋Ÿฐ ๊ฒƒ์„ side effect๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•ด์š”.

    ์ด๋ ‡๊ฒŒ side effect๋ฅผ ํ—ˆ์šฉํ•ด์ฃผ๋Š” ๊ณณ์€ 2๊ตฐ๋ฐ๊ฐ€ ์žˆ์–ด์š”.

    ๋ฐฉ๊ธˆ ๋ณธ subscribe, ๊ทธ๋ฆฌ๊ณ  do๊ฐ€ ์žˆ์–ด์š”.


    do๋Š” subscribe์™€ ๋‹ค๋ฅด๊ฒŒ stream์ด ์ง€๋‚˜๊ฐ€๋Š” ๋™์•ˆ ๊ทธ๋ƒฅ ์ž‘์—…์„ ํ•œ ๋ฒˆ ํ•ด์ฃผ๋Š” ๊ฑฐ์—์š”.

    ๊ฒฐ๋ก ์ ์œผ๋กœ ์™ธ๋ถ€์— ์˜ํ–ฅ์„ ๋ผ์น˜๋Š” side effect๋ฅผ ์ฒ˜๋ฆฌํ•ด์•ผํ•œ๋‹ค -> do๋‚˜ subscribe์—์„œ ํ•ด์ฃผ๋ฉด ๋˜์š”!


  • ์ด๋ฒˆ ๊ธ€์€ ์—ฌ๊ธฐ์„œ ๋งˆ๋ฌด๋ฆฌ ํ• ๊ฒŒ์š”!

ReactiveX

RxSwift by ๊ณฐํŠ€๊น€

๋ฐ˜์‘ํ˜•
๋Œ“๊ธ€
๋ฐ˜์‘ํ˜•
๊ณต์ง€์‚ฌํ•ญ
์ตœ๊ทผ์— ์˜ฌ๋ผ์˜จ ๊ธ€
์ตœ๊ทผ์— ๋‹ฌ๋ฆฐ ๋Œ“๊ธ€
Total
Today
Yesterday
๋งํฌ
TAG more
ยซ   2024/11   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
๊ธ€ ๋ณด๊ด€ํ•จ