[번역] RunLoop.main과 DispatchQueue.main의 차이

도윤·2022년 12월 29일
1
post-thumbnail

Combine을 공부하다가 주로 receive(on: ) 을 통해 메인 스레드 혹은 Runloop.main으로 스레드를 변경할 때가 있습니다.

어떤 차이점이 있는지 궁금해서 알아보았습니다.

번역을 통해 진행하였습니다.

https://www.avanderlee.com/combine/runloop-main-vs-dispatchqueue-main/

What is a Combine scheduler?

Combine scheduler란 클로저가 언제, 어떻게 실행될지를 정의하는 것이다.

Scheduler들은 Scheduler 프로토콜을 따르고 있고, RunLoop.main과 DispatchQueue.main 또한 따르고 있다.

가장 흔히 사용되는 예시는 receive(on: option:) 으로 Combine stream을 설정(setting up)할 때 사용된다.

URLSession.shared
    .dataTaskPublisher(for: URL(string: "https://picsum.photos/300/600")!)
    .map(\.data)
    .compactMap(UIImage.init)

    /// Schedule to receive the sink closure on the
    /// main dispatch queue.
    .receive(on: DispatchQueue.main, options: nil)
    .sink { _ in
        print("Image loading completed")
    } receiveValue: { image in
        self.image = image
    }.store(in: &cancellables

위 코드에서 확인할 수 있듯이, Image를 할당하는 것을 메인스레드에서 하도록 만들 수 있다.

main queue scheduler는 main thread에서 UI업데이트 하도록 할 때 요구된다.

What is RunLoop.main?

RunLoop은 Application의 touch와 같은 input source들을 다루는 object의 인터페이스이다.

RunLoop은 각 쓰레드의 object를 위해 RunLoop object를 생성하는 시스템에 의해 생성되고 관리된다.

메인 스레드를 나타내는 Main Run Loop도 생성한다.

What is DispatchQueue.main?

DispatchQueue.main은 현재 프로세스의 메인스레드와 관련이 있는 dispatch Queue이다.

DispatchQueue는 관련된 스레드에서 직렬 혹은 병렬로 작업을 실행한다.

RunLoop.main and DispatchQueue.main are the same but different

RunLoop.main과 DispatchQueue.main은 메인 스레드에서 UI를 업데이트 하는데 모두 사용된다.

둘 다 Combine value가 publishe된 이후에 UI 업데이트를 하도록 해준다.

The Differences between RunLoop.main and DispatchQueue.main

가장 큰 차이점은 DispatchQueue는 즉시 실행되는 것이고 반면에 RunLoop은 busy할지도 모른다.

만약 DispatchQueue.main을 스케줄러로 사용할 때는, 스크롤하면서 동시에 UI가 업데이트 된다.

반면에 RunLoop.main은 스크롤이 마친 이후에 UI가 업데이트 된다.

즉, main run loop에 의해 scheduled된 클로저는 유저 Interation이 발생하면 즉시 실행되지 않고 끝나야 실행된다.

Understanding the behaviour of the main RunLoop

main run loop은 여러개의 모드를 사용한다. 아래중에서 iOS는 common, default, traking 모드만 지원을 한다.

유저 Interation이 발생하면 non-default모드로 변경된다. 그러나 RunLoop.main은 오직 default모드에서만 실행(active)된다. 달리 말하면, User interation이 끝날 때 Default Mode로 바뀌게 되고 closure가 실행된다.

Default로 DispatchQueue.main을 사용하면 될 것 같다.

UI를 업데이트하기 전에 처리해야할 User Interation이 있다면 RunLoop.main

스크롤하는동안 UI를 업데이트하면 Frame per second(FPS)에 영향을 주고 스크롤하는데 영향을 줄 것이다.

스크롤 할 때 UI업데이트가 필요하지 않을 수도 있다. 이경우엔 RunLoop.main

0개의 댓글