본문 바로가기
IOS🍎/Combine

[Combine] Scheduler란

by Jouureee 2023. 4. 16.

무려 1년만의 combine 글 작성.... 이내요....ㅎ

오늘은 이러쿵 저러쿵 공부를 하던 와중 combine이 머였더라 .. ㅎ 하고 복습을 하게 되었고 Scheduler 정리를 드디어 하려구 합니다

 

Scheduler

closure의 실행 시기와 방법을 정의하는 프로토콜

그렇습니다. scheduler도 프로토콜이네요 !

protocol Scheduler<SchedulerTimeType>

 

공식문서 Overview를 보면

You can use a scheduler to execute code as soon as possible, or after a future date. Individual scheduler implementations use whatever time-keeping system makes sense for them. Schedulers express this as their SchedulerTimeType. Since this type conforms to SchedulerTimeIntervalConvertible, you can always express these times with the convenience functions like .milliseconds(500). Schedulers can accept options to control how they execute the actions passed to them. These options may control factors like which threads or dispatch queues execute the actions.

- 스케줄러를 사용하여 특정 시간, 날짜 이후에 코드를 실행하도록 할 수 있다.

- 개별 스케줄러를 구현하는 경우 시간 유지(time keeping) 시스템인걸 사용한다.

- 스케줄러는 자신의 SchedulerTimeType을 사용한다.

- 스케줄러에 옵션을 사용해 스레드, 디스패치 큐 등을 제어할 수 있다.

 

우선 Combine에서는 기본적으로 스케줄러를 설정해주지 않아도

default 스케줄러를 따르는데여. 즉 element가 만들어진 쓰레드가 곧 기본 스케줄러의 쓰레드가 됩니다.

 

element가 무거운 작업이라 메인 쓰레드가 아닌 다른 쓰레드에서 생성이 필요로 되는 경우가 있겠죠 ?

그럴 경우에 스케줄러를 스위칭하여 작업이 발생하는 곳을 바꿔줄 수 있습니다.

subscribe(on:), receive(on:) 으로 스위칭 작업을 수행하는데요. 하나씩 봅시다.

 

subscribe(on: Scheduler)

publisher가 어느 스레드에서 subscribe 할지 결정하는 역할을 합니다. 

예시를 봅시다. (예시 참고)

Just(1)
   .subscribe(on: DispatchQueue.global())
   .map { _ in print(Thread.isMainThread) }
   .sink { print(Thread.isMainThread) }
   
   
 //false
 //false

subscribe하는 곳을 DispatchQueue.global() Scheduler으로 변경하였으므로 false가 출력됩니다.

그리고 예시에서는 subscribe(on:) 하는 곳의 위치는 상관이 없다고 말하는데요.

흠 실제 테스트 해보았을때 Combine의 경우 위치에 영향이 있었습니다

 

즉 map operator 구문과 자리를 바꾸면 결과가 달라집니다 ! 즉 subscribe(on:)은 upstream에만 영향을 미칩니다.

Just(1)
   .map { _ in print(Thread.isMainThread) }
   .subscribe(on: DispatchQueue.global())
   .sink { print(Thread.isMainThread) }
   
   
 //true
 //false

 

 

receive(on: Scheduler)

publisher로부터 element를 수신할 oerator, scheduler를 지정하는 역할을 합니다.

즉 publisher가 방출한 element를 어디로(main, background)로 수신 받을 것인지 스위칭해줍니다.

 

아래 예시를 보면

let publisher = JSONLoaderPublisher()
publisher.subscribe(on: backgroundQueue)
.receive(on: Runloop.main)
.sink { value in 
	self.label.text = value
}

background에서 받아온 데이터로 UI를 업데이트 하기전 main thread로 schedular의 위치를 변경해주고 있습니다.

 

 

참고. 

https://developer.apple.com/documentation/combine/scheduler

 

Scheduler | Apple Developer Documentation

A protocol that defines when and how to execute a closure.

developer.apple.com

https://www.vadimbulavin.com/understanding-schedulers-in-swift-combine-framework/

 

Understanding Schedulers in Swift Combine Framework

Let's learn what are schedulers in Swift Combine Framework along with several related topics: which schedulers are built into Combine? What's the difference between receive(on:) and subscribe(on:)? How to switch schedulers? How to perform asynchronous work

www.vadimbulavin.com

'IOS🍎 > Combine' 카테고리의 다른 글

[Combine] Cancellable이란  (0) 2023.04.17
[Combine] ConnectablePublisher  (0) 2022.05.03
[Combine] Subject란 (AnyPublisher)  (0) 2022.04.17
[Combine] Combine, Publisher, Subscriber 에 대해서  (0) 2022.04.17

댓글