RxSwift(4)

EN·2023년 7월 1일
0

iOS_rxswift

목록 보기
4/4

observeOn과 scheduler

    @IBAction func exMap3() {
        Observable.just("800x600")//단순 값은 just!
            .observeOn(ConcurrentMainScheduler.instance)
            .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(MainScheduler.instance)
            .subscribe(onNext: { image in
                self.imageView.image = image
            })
            .disposed(by: disposeBag)
    }

여기서 ConcurrentMainSceduler와 MainScheduler를 따로 놓는 이유는?

  • ConcurrentMainScheduler의 Summary에는 "Abstracts work that needs to be performed on MainThread. In case schedule methods are called from main thread, it will perform action immediately without scheduling."

  • MainScheduler의 Summary는 전자와 매우 비슷하다. "Abstracts work that needs to be performed on DispatchQueue.main. In case schedule methods are called from DispatchQueue.main, it will perform action immediately without scheduling."

근데 MainThread나 DispatchQueue.main이나 똑같은거 아닌가? 라고 생각했다.
밑에 Discussion을 보니

  • ConcurrentMainScheduler discussion : This scheduler is optimized for subscribeOn operator. If you want to observe observable sequence elements on main thread using observeOn operator, MainScheduler is more suitable for that purpose.

  • MainScheduler discussion : This scheduler is usually used to perform UI work.
    Main scheduler is a specialization of SerialDispatchQueueScheduler.
    This scheduler is optimized for observeOn operator. To ensure observable sequence is subscribed on main thread using subscribeOn operator please use ConcurrentMainScheduler because it is more optimized for that purpose.

읽다보니, subscribeOn과 observeOn에 대해 궁금한게 생겼다.

subscribeOn vs observeOn

참고 : https://jouureee.tistory.com/169

결론 먼저 말하자면
subscribeOn은 subscription code가 실행될 스케줄러를 바꾸는 메소드이고,
observeOn은 observation code가 실행될 스케줄러를 바꾸는 메소드인것.

그 전에 알고 넘어가야할 사항이 있는데 뭐냐면

Cocoa의 GCD개념과 대응되는게 RxSwift의 Scheduler인 것이다.

실행 흐름과 그 디테일들을 보자.

1번에서 Observable을 정의함(쉽게말하면 변화 대상들을 등록하는것)
단, create라고 써져 있음에도 1번 줄에서는 실제 실행은 되지 않는다. 여기서는 미래에 사용할 값들을 저장하는 것!!

2번에서는 operators들을 통한 stream들을 정의하는 것임. 이것도 마찬가지로
실제 실행은 되지 않음!

3번에서 실제 실행이 이루어짐. 1번과 2번에 있는 것들을 실행하게 되는것이다.

예시를 보자.

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은 Observable의 생성을 누가 할건지를 지정한다고 했었다.
[main] subscribe() -> [background] create{} -> [background] onNext{}...

만약에, subscribe에서 UI작업이 동반된다고 하자.
UI작업은 무조건 MainThread에서 수행해야한다. 그래서 값을 방출할 때 스케줄러 변경이 필요하다면 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
	self.loginButton.isSelected = true // UI변경
})

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

profile
iOS/JUJITSU

0개의 댓글