๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
IOS๐ŸŽ/RxSwift

[RxSwift] Schedular๋ž€ (subscribeOn, observeOn)

by Jouureee 2022. 4. 29.

์ด๋ฆ„์€ ์กฐ๊ธˆ ๋‹ค๋ฅด์ง€๋งŒ ์–ด๋Š ๊ณณ์—์„œ ์ž‘์—… ํ• ์ง€(main, global) ์‹คํ–‰ ํ๋ฆ„์˜ ์œ„์น˜๋ฅผ ์ง€์ •ํ•ด์ฃผ๋Š” ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ swift์—์„œ๋Š” thread ์ž‘์—…์„ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด GCD๋ฅผ ์‚ฌ์šฉํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค. RxSwift์—์„œ GCD์— ๋Œ€์‘๋˜๋Š” ๊ฐœ๋…์ด Schedular๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 
Schedular๋ฅผ ํ†ตํ•ด Observable์„ ์–ด๋””์„œ ์ƒ์„ฑํ• ์ง€, Observer๊ฐ€ ์–ด๋””์„œ ๊ด€์ฐฐํ• ์ง€ ์ง€์ •ํ•ด ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

observeOn ๊ณผ subscribeOn์€ ์Šค์ผ€์ค„๋Ÿฌ๋กœ ์ž‘๋™๋˜๋Š” ๋Œ€ํ‘œ์ ์ธ ๋‘ ์—ฐ์‚ฐ์ž์ž…๋‹ˆ๋‹ค.

observeOn๊ณผ subscribeOn

๋‘˜์˜ ์ฐจ์ด๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌ๋ถ„ํ•˜๋Š”๋ฐ ์žˆ์–ด

http://rx-marin.com/post/observeon-vs-subscribeon/

 

observeOn vs. subscribeOn

How to subscribe and observe on different threads

rx-marin.com

์ด ๊ธ€์„ ์ฐธ๊ณ ํ–ˆ์Šต๋‹ˆ๋‹ค (์„ค๋ช… ์งฑ ๐Ÿ‘๐Ÿ‘)

 

observeOn๊ณผ subscribeOn์˜ ์˜ˆ์ œ๋ฅผ ๋ณด๊ธฐ ์ „์— observable์ด subscription ๋˜๋Š” ํ๋ฆ„์„ ๋จผ์ € ์‚ดํŽด๋ด…์‹œ๋‹ค.
์•„๋ž˜ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด 3๋‹จ๋ฝ์œผ๋กœ ๊ตฌ๋ถ„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. observable์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. observable์„ create๋กœ ์ƒ์„ฑํ• ๋•Œ ์ด๊ฒƒ์€ ์•„์ง ์ƒ์„ฑ๋˜์—ˆ์Œ์„ ๋‚˜ํƒ€๋‚ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. observable๋Š” subscribe๋˜์—ˆ์„ ๋•Œ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ด๊ณณ์—์„  ๋ฏธ๋ž˜์— ์‚ฌ์šฉํ•  ๊ฐ’๋“ค์„ ์ €์žฅํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  2. Map, filter๊ณผ ๊ฐ™์€ operator์„ ์‚ฌ์šฉํ•ด ๊ฐ’์„ ๋ฐฉ์ถœํ•ฉ๋‹ˆ๋‹ค. ์—ฌ์ „ํžˆ ์•„๋ฌด ์ž‘์—…๋„ ์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  3. subscribe(…)๋ฅผ ํ˜ธ์ถœํ• ๋•Œ ์‹คํ–‰์ด ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. 

์—ฌ๊ธฐ์—” ๋‘๊ฐ€์ง€ ํฌ์ธํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. 
Observable.create {} ์ฝ”๋“œ๋Š” (subscription code) subscribe() ๋ฉ”์†Œ๋“œ๋กœ๋ถ€ํ„ฐ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

์ด ํ•จ์ˆ˜๋Š” subcription์„ ๋งŒ๋“ค๊ณ  element๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

subscribe()  ์ฝ”๋“œ๋Š” (observation code) ๋ฐฉ์ถœ๋œ ๊ฐ’์„ ๊ด€์ฐฐํ•˜๋Š” ๊ณณ์ž…๋‹ˆ๋‹ค. 

subscribeOn

Subscription code๊ฐ€ ์‹คํ–‰๋  ์Šค์ผ€์ค„๋Ÿฌ๋ฅผ ๋ฐ”๊พธ๋Š” ๋ฉ”์†Œ๋“œ์ž…๋‹ˆ๋‹ค. 

๊ธฐ๋ณธ์ ์œผ๋กœ observable์˜ ์ƒ์„ฑ์€ subscribe()๋ฅผ ํ˜ธ์ถœํ•œ ์Šค๋ ˆ๋“œ์—์„œ ๋ถˆ๋ฆฝ๋‹ˆ๋‹ค. 

subscribeOn() ๋ฉ”์„œ๋“œ๋Š” observable์„ ์ƒ์„ฑํ•  ์Šค๋ ˆ๋“œ๋ฅผ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

 

Observable<Int>.create { observer in
    observer.onNext(1)
    sleep(1)
    observer.onNext(2)
    return Disposables.create()
}
.subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background))
.subscribe(onNext: { el in
    print(Thread.isMainThread)
})

์œ„ ์ฝ”๋“œ์—์„œ subscribeOn์ด ์“ฐ์˜€์Šต๋‹ˆ๋‹ค. subscribeOn์˜ ์—ญํ• ์— ๋Œ€์ž…ํ•ด ๋ณธ๋‹ค๋ฉด
observable()์ด ์ƒ์„ฑํ•  ์Šค์ผ€์ค„๋Ÿฌ๋ฅผ ๋ฐ”๊ฟ”์ฃผ๋Š”๋ฐ, concurrent schedular๋กœ background์—์„œ ํ•˜๋„๋ก ๋ฐ”๊ฟ”์ฃผ๊ณ  ์žˆ๋‹ค๋Š” ๋œป์ด๊ฒ ์ฃ  ?

 

[main] subscribe() -> [background] create{ … } -> [background] onNext { … }

์˜ ์‹คํ–‰ ํ๋ฆ„์„ ๊ฐ€์ง€๋ฉฐ false๋ฅผ ์ถœ๋ ฅํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. 

๋งŒ์•ฝ subscribe() ํ•จ์ˆ˜ ๋‚ด์—์„œ

.subscribe(onNext: { el in
	self.loginButton.isSelected = true
})

์™€ ๊ฐ™์€ UI ์ž‘์—…์ด ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ด…์‹œ๋‹ค.. ์•„๋‹ˆ ๊ทธ๋Ÿฌ๋ฉด ๋‹น๊ทผ main ์Šค๋ ˆ๋“œ์—์„œ ์ž‘๋™ํ•ด์•ผ ํ•˜๊ฒ ์ฃ  ? 

 

.subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background))

๋ฅผ ํ†ตํ•ด ์ž‘์—…์˜ ํ๋ฆ„์„ background๋กœ ๋ฐ”๊ฟ”์คฌ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์‹œ main ์Šค๋ ˆ๋“œ๋กœ ์˜ฎ๊ฒจ์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ observeOn() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

observeOn()

Observation code๊ฐ€ ์‹คํ–‰๋  ์Šค์ผ€์ค„๋Ÿฌ๋ฅผ ๋ฐ”๊พธ๋Š” ๋ฉ”์†Œ๋“œ ์ž…๋‹ˆ๋‹ค.

๊ฐ’์„ ๋ฐฉ์ถœํ• ๋•Œ ์Šค์ผ€์ค„๋Ÿฌ๋ฅผ ๋ณ€๊ฒฝํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค๋ฉด ๋ณดํ†ต observeOn() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹คํ–‰ ํ๋ฆ„์„ ๋ฐ”๊ฟ”์ค๋‹ˆ๋‹ค.

 

Observable<Int>.create { observer in
    observer.onNext(1)
    sleep(1)
    observer.onNext(2)
    return Disposables.create()
}
.observeOn(MainScheduler.instance)
.subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background))
.subscribe(onNext: { el in
    print(Thread.isMainThread)
})

์ด๋ ‡๊ฒŒ ๋œ๋‹ค๋ฉด observable์„ ์ƒ์„ฑํ• ๋•Œ๋Š” background์—์„œ onNext๋กœ ๊ฐ’์„ ๋ฐฉ์ถœํ• ๋• main thread์—์„œ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

[main] subscribe() -> [background] create{ ... } -> [main] onNext { ... }

 

subscribOn()์€ ์‚ฌ์šฉํ•ด๋ณธ์ ์ด ์—†์–ด์„œ observable์˜ ์ƒ์„ฑ์„ background์—์„œ ํ•˜๋Š” ๊ฒฝ์šฐ์— ๋Œ€ํ•ด ์˜ˆ์ œ๋ฅผ ํ•œ๋ฒˆ ์‚ดํŽด ๋ด์•ผ ํ• ๊ฑฐ ๊ฐ™์•„์š” .. ๊ทธ๋Ÿผ ์ด๋งŒ !! 

 

์ฐธ๊ณ  : https://github.com/ReactiveX/RxSwift/blob/main/Documentation/Schedulers.md

 

GitHub - ReactiveX/RxSwift: Reactive Programming in Swift

Reactive Programming in Swift. Contribute to ReactiveX/RxSwift development by creating an account on GitHub.

github.com

'IOS๐ŸŽ > RxSwift' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[RxSwift] Filtering Operator (distinctUntilChanged)  (0) 2022.05.10
[RxSwift] Error Handling Operator  (0) 2022.05.10
[RxSwift] Signal, ControlProperty, ControlEvent ๋ž€ ?  (0) 2022.03.21
[RxSwift] Driver๋ž€ ? (feat. bind)  (0) 2022.03.21
[RxSwift] Traits ์ด๋ž€  (0) 2022.03.19

๋Œ“๊ธ€