Schedulers
๐งญ Schedulers โ RxSwift์ โ์คํ ์ปจํ
์คํธโ ๊ด๋ฆฌ
โsubscribeOn์ ์์์ ์, observeOn์ ๊ด์ฐฐ ์ง์ ์ ๋ฐ๊พผ๋ค.โ
SchedulerType
์ Observable ์ฐ์ฐ์ด ์ด๋ ์ค๋ ๋/ํ์์ ์คํ๋ ์ง ๊ฒฐ์ ํฉ๋๋ค. ๋์์ฑ ์ฝ๋๋ ์ ์ธํ ์ฒด์ธ์ ๋
น์ฌ ๊ฐ๋
์ฑ๊ณผ ์์ ์ฑ์ ๋์ผ ์ ์์ต๋๋ค.
1๏ธโฃ ์ฃผ์ Scheduler ์ข
๋ฅ
MainScheduler
๋ฉ์ธ ์ฐ๋ ๋
UI ์
๋ฐ์ดํธ ํ์, Drive
, bind(to:)
๊ธฐ๋ณธ ๊ฐ
CurrentThreadScheduler
ํ์ฌ ํธ์ถ ์คํ
๋ํดํธ(Cold Observable) โ ์ฌ๊ท ์ ์คํ ์ค๋ฒํ๋ก์ฐ ์ฃผ์
SerialDispatchQueueScheduler
GCD Serial Queue
์๋ฆฌ์ผ ์์ , ๋ฐ์ดํฐ๋ฒ ์ด์ค I/O, ํ์ผ ์ฐ๊ธฐ
ConcurrentDispatchQueueScheduler
GCD Concurrent Queue
CPUโbound ๊ณ์ฐ, ํ์ฑ, ์ด๋ฏธ์ง ํํฐ
OperationQueueScheduler
OperationQueue
์์กด์ฑยท์ฐ์ ์์ ์ ์ด ํ์ ์
ImmediateSchedulerType
์ฆ์ ์คํ
ํ ์คํธยท๋๊ธฐ ์์ ์ต์ ํ
TestScheduler
๊ฐ์ ์๊ฐ
๋จ์ ํ ์คํธ, Marble ํ ์คํธ ๊ตฌ์ถ
2๏ธโฃ subscribe(on:) vs observe(on:)
subscribe(on:)
์์ฐ ๋จ๊ณ(Observable ์์ฑ) ์ค์ผ์ค๋ฌ ์ง์
โ๋ํ ์์ง์ ์ฃผ๋ฐฉ์์ ์์โ
observe(on:)
์๋น ๋จ๊ณ ์ดํ ์ฒด์ธ ์คํ ์ค์ผ์ค๋ฌ ๋ณ๊ฒฝ
โ์์ง๋ ์ฌ๋ฃ๋ฅผ ํ ์๋น ํ ์ด๋ธ์์ ๋ง๋ฌด๋ฆฌโ
URLSession.shared.rx.data(request: req)
.subscribe(on: ConcurrentDispatchQueueScheduler(qos: .background)) // ๋คํธ์ํฌ ๋ฐฑ๊ทธ๋ผ์ด๋
.map(parseJSON)
.observe(on: MainScheduler.instance) // ๊ฒฐ๊ณผ UI ๋ฐ์ธ๋ฉ
.bind(to: tableView.rx.items(cellIdentifier: "Cell")) { _, model, cell in
cell.textLabel?.text = model.title
}
.disposed(by: bag)
3๏ธโฃ ์ค์ ํจํด
A. ๋น๋๊ธฐ ์ด๋ฏธ์ง ์ฒ๋ฆฌ
imagePicker.rx.selectedImage
.subscribe(on: ConcurrentDispatchQueueScheduler(qos: .userInitiated))
.map(ImageProcessor.resize)
.observe(on: MainScheduler.instance)
.bind(to: imageView.rx.image)
.disposed(by: bag)
B. CoreData ์ ์ฅ
saveTrigger
.withLatestFrom(input)
.observe(on: SerialDispatchQueueScheduler(qos: .utility))
.flatMap(saveToCoreData)
.observe(on: MainScheduler.instance)
.subscribe(onNext: showToast)
.disposed(by: bag)
4๏ธโฃ TestScheduler โ ๊ฐ์ ์๊ฐ ๋จ์ ํ
์คํธ
let scheduler = TestScheduler(initialClock: 0)
let hot = scheduler.createHotObservable([
.next(100, 1), .next(200, 2), .completed(300)
])
let res = scheduler.start { hot.map { $0 * 2 } }
XCTAssertEqual(res.events, [
.next(100, 2), .next(200, 4), .completed(300)
])
๊ฐ์ ์๊ฐ์ผ๋ก ๋๊ธฐ ํ ์คํธ ์์ฑ โ ํ ์คํธ ์๋ โฌ๏ธ, ์ฌํ์ฑ โฌ๏ธ.
5๏ธโฃ Deadlock & Race Condition ๋ฐฉ์ง
๋ฉ์ธ โ ๋ฉ์ธ ์ฌ์ ๋ ฅ: Observable ์ฒด์ธ ์ค ๋ค์ MainScheduler๋ก ์ ํ ์ ์ค์ฒฉ DispatchQueue ํธ์ถ ์ง์.
Shared Mutable State: SerialScheduler๋ก ๋ณดํธํ๊ฑฐ๋
Actor
(Swift Concurrency) ์ฌ์ฉ.subscribeOn ์ค๋ณต: ๊ฐ์ฅ ์ฒ์์ ์์นํ subscribeOn๋ง ์ ์ฉ.
6๏ธโฃ Best Practices Checklist โ
7๏ธโฃ Mini Quiz
observe(on:)
๋ฅผ ์ฐ์ ๋ ๋ฒ ํธ์ถํ๋ฉด ์ด๋ป๊ฒ ๋์ํ ๊น?subscribe(on:)
์ผ๋ก MainScheduler,observe(on:)
์ผ๋ก Background ์ง์ ์ UI ์์ ์ ํ๋ฉด ๋ฌด์จ ๋ฌธ์ ๊ฐ?TestScheduler
์ฌ์ฉ ์ Cold Observable๊ณผ Hot Observable์ ์ฐจ์ด๋?
๐ Schedulers ์น์ ์๋ฃ! ์ด์ Sequences ์นดํ ๊ณ ๋ฆฌ๋ก ๋์ด๊ฐ ์คํธ๋ฆผ ์์ ๋ง์คํฐํด ๋ณด์ธ์. ๐
Last updated