Swift - QoS, RxSwift: 스케줄러
The Complete Guide to Concurrency and Multithreading in iOS 참고
GCD(Grand Central Dispatch)
멀티코어 하드웨어에서, 동시 코드 실행을 지원하기 위한 Apple의 저수준 스레딩 인터페이스
QoS(Quality of Service)
작업의 우선순위를 결정할 때 사용
iOS 앱용 에너지 효율 가이드 참고
QoS | 작업 타입과 포커스 | 작업 수행 시간 | 비고 |
---|---|---|---|
User-interactive | <ul><li>메인 스레드 작업, 사용자 인터페이스 새로 고침, 애니메이션 수행 등 사용자와 상호 작용하는 작업</li><li>작업이 빨리 진행되지 않으면 사용자 인터페이스가 정지된 것처럼 보일 수 있음</li><li>응답성과 성능에 중점</li></ul> | 즉각적으로 | |
User-initiated | <ul><li>저장된 문서를 열기, 사용자가 사용자 인터페이스에서 무언가를 클릭할 때 작업 수행 등 사용자가 시작하여 즉각적인 결과가 필요한 작업</li><li>사용자 상호 작용을 계속하려면 해당 작업이 필요함</li><li>응답성과 성능에 중점</li></ul> | 몇 초 이내 | |
Utility | <ul><li>데이터 다운로드 등 완료하는 데 시간이 걸릴 수 있고 즉각적인 결과가 필요하지 않은 작업</li><li>일반적으로 사용자가 볼 수 있는 진행률 표시줄 등</li><li>응답성, 성능 및 에너지 효율성 간의 균형을 제공하는 데 중점</li></ul> | 몇 초 ~ 몇 분 | 사용자와 상호작용이 없을 때 90% 정도는 Utility와 Background로 실행하여 최적화해야 함 |
background | <ul><li>인덱싱, 동기화 및 백업과 같이 백그라운드에서 작동하며 사용자에게 표시되지 않는 작업</li><li>에너지 효율성에 중점</li></ul> | 몇 분 ~ 시간 | 저전력 모드에서는 백그라운드 작업 일시 중지 됨 |
추가적으로 Default, Unspecified가 있지만 개발자 입장에서 작업을 분류하는 데 잘 사용하지는 않음
RxSwift의 스케줄러
MainScheduler
Serial.
MainThread에서 수행해야 하는 작업을 추상화, 메인 쓰레드에서 스케쥴 메소드가 호출되는 경우 스케쥴링 없이 즉시 작업을 수행
SerialDispatchQueueScheduler
Serial.
특정 dispatch_queue_t에서 수행해야 하는 작업을 추상화, concurrent 디스패치 큐가 전달되더라도 serial로 변환한다고 함
serial 스케줄러는 observeOn에 대한 특정 최적화
MainScheduler는 SerialDispatchQueueScheduler의 인스턴스
ConcurrentDispatchQueueScheduler
Concurrent.
특정 dispatch_queue_t에서 수행해야 하는 작업을 추상화, serial 큐를 전달할 수도 있음
백그라운드 작업에 적합
OperationQueueScheduler
Concurrent.
특정 NSOperationQueue에서 수행해야 하는 작업을 추상화
백그라운드에서 수행해야 하는 더 큰 작업이나, maxConcurrentOperationCount를 사용하여 동시 처리를 미세 조정하려는 경우에 적합
observeOn()
, subscribeOn()
observeOn() 과 subscribeOn() 입니다.
화살표 색을 잘 봐주시면, observeOn(주황), subscribeOn(파랑), observeOn(분홍) 순으로 쓰여져 있지만 스트림의 시작 부분이 파랑이고, observeOn(주황) 이후부터 주황색에서 동작하고, observeOn(분홍) 이후부터 분홍색이 됨
그냥 슥 보면 음? subscribeOn 굳이? 순서만 헷갈리게 하고 왜 이럼? 싶은데
생각해 보니 observeOn만 가지고는 해당 Observable의 처음을 바꿀 수 없는 듯
subscribeOn()
- 특정 스케줄러에서 작업을 수행하도록 Observable에 지시
- Observable이 작동해야 하는 다른 스케줄러를 지정하여 이 동작을 변경
observeOn()
- Observable이 지정된 스케줄러의 관찰자에게 알림을 보내도록 지시
- Observable이 관찰자에게 알림을 보내는 데 사용할 다른 스케줄러를 지정
공식문서 보면 어감이 꽤 다르긴 하네요
someObservable
.subscribe(on: MainScheduler.instance)
.do { 로딩 중 등 애니메이션 작업 }
.observe(on: ConcurrentDispatchQueueScheduler(qos: .utility))
.flatMap(네트워크 요청)
.observe(on: MainScheduler.instance)
.subscribe {
로딩 끝내기 등 UI 작업
결과 보여주기
}
.disposed(by: disposeBag)
간단하게 코드로 보면 요런 느낌일 듯
우선 메인에 subscribeOn 해서 로딩 중 애니메이션 띄우고, 그 뒤부터는 백그라운드에서 observeOn하고, 작업 끝나면 다시 메인에서 결과 보여주기
굿
댓글남기기