관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] RxSwift의 Scheduler 이해하기 (#GCD와 Scheduler 차이점, MainScheduler, SerialDispatchQueueScheduler, ConcurrentDispatchQueueScheduler, OperationQueueScheduler) 본문

iOS 응용 (swift)

[iOS - swift] RxSwift의 Scheduler 이해하기 (#GCD와 Scheduler 차이점, MainScheduler, SerialDispatchQueueScheduler, ConcurrentDispatchQueueScheduler, OperationQueueScheduler)

jake-kim 2023. 8. 10. 01:17

사전지식) RxSwift의 GCD 종류

1) main (serial)

  • main thread에서 처리되는 serial queue (모든 UI관련 작업은 해당 큐에서 main queue에서 실행)

2) global (concurrent)

  • 전체 시스템에서 공유되는 concurrent queue이고, concurrent이기 queue끼리의 우선순위를 위해서 queue를 사용할 때 QoS 설정 필요
    • userInteractive: 유저가 누르면 즉각 반응 (main queue)
    • userInitiated: 유저가 실행시킨 작업들을 즉각적이지는 않지만, async하도록 처리
    • default
    • utility: I/O, n/w API 호출
    • background: 유저가 인지하지 못할 정도의 뒷단에서 수행하는 작업

3) 커스텀

  • 개발자가 임의로 정의한 queue이고 serial / concurrent 모두 정의 가능
    • 기본적으로 주어진 것은 main은 serial, global은 concurrent이므로 main이 아닌 뒷단에서 serial로 수행하고 싶은 경우 사용

RxSwift의 Scheduler

  • Swift의 DispatchQueue와 의미가 동일하며, RxSwift에서 일을 수행할 때 어디서 수행할지(main, background, concurrent, serial) 정해주는 것
Swift의 DispatchQueue RxSwift의 Scheduler
(main) DispatchQueue.main MainSchduler
(background) DispatchQueue(label: "my_queue") SerialDispatchQueueScheduler
(background) DispatchQueue(label: "my_queue", attributes: .concurrent) ConcurrentDispatchQueueScheduler
(background) OperationQueue OperationQueueScheduler

ex) 데이터를 다룰 때 background에서 데이터 접근이 동시에 일어나지 않도록 serial queue로 업데이트 하고 싶은 경우

  • SerialDispatchQueueScheduler 하나를 선언해 놓고 데이터 setter, getter 모두 이 큐 안에서 동작하도록 구현
import UIKit
import RxSwift

class ViewController: UIViewController {
    private let disposeBag = DisposeBag()
    private var data = 1
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let backgroundSerialQueue = SerialDispatchQueueScheduler(qos: .background)
        
        Observable
            .just(())
            .observe(on: backgroundSerialQueue)
            .subscribe { [weak self] _ in
                self?.data = (1...100).randomElement()!
            }
            .disposed(by: disposeBag)
        
        Observable
            .just(())
            .observe(on: backgroundSerialQueue)
            .subscribe { [weak self] _ in
                print(self?.data)
            }
            .disposed(by: disposeBag)
    }
}

* 참고

https://github.com/ReactiveX/RxSwift/blob/main/Documentation/Schedulers.md

https://ios-development.tistory.com/746

Comments