DispatchQueue를 사용할 때 백그라운드로 작업을 보내기 위해서 다음과 같은 코드를 사용하곤 합니다.

DispatchQueue.global().async {
    // do work...
}

여기서 global을 자연스럽게 인자 없이 쓰고 있긴 하지만, global의 선언을 보면 다음과 같습니다.

class func global(qos: DispatchQoS.QoSClass = .default) -> DispatchQueue // qos??

qos라는 것이 눈에 띄입니다. 오늘은 이 qos에 대해서 알아보도록 하겠습니다.

Qos는 Quiality-of-service(서비스 품질)의 약자입니다. Qos는 원래 네트워크에서 사용하는 용어로 서비스의 중요도에 따라 중요한 서비스에 더 많은 자원을 할당하는 것, 또는 이 중요도를 뜻하는 말입니다. Qos가 없다면 모든 서비스는 동일한 비율의 자원을 할당받게 됩니다. 하지만 작업들 중에는 급하게 처리해야만 하는 작업이 있을 수 있고, 천천히 처리되어도 괜찮은 작업이 있을 수 있습니다. 이것을 중요도에 따라 구분해서 급하게 처리되어야 하는 작업에는 자원을 집중적으로 할당해서 빠르게 처리하고, 중요도가 낮은 작업은 자원이 모자랄 때 자원 할당을 덜해주는 등의 판단을 시스템이 할 수 있게 해줍니다.

애플리케이션에서 이 Qos는 백그라운드 작업들을 시스템이 실행하는 최선의 방법을 결정하기 위한 정보를 제공해줍니다. 예를 들어 사용자와 상호작용하는 작업을 포함하는 스레드에는 높은 우선순위를 주어 앱이 끊기는 느낌 없이 최대한 빨리 반응하도록 한다거나, 백그라운드 작업에는 낮은 우선순위를 주어 저전력 코어에 작업을 할당한다던지 할 수 있게 됩니다. 다만 이러한 판단은 시스템이 Qos와 더불어 현재 상태나 스케쥴링 하려는 작업의 속성을 보고 내리는 것이고, Qos가 절대적이진 않습니다. 하지만 시스템이 적절한 판단을 내리도록 유도한다는 점에서 Qos를 적절히 지정해주는 것이 성능과 에너지 효율 등에서 유리합니다.

  1. userInteractive: 가장 높은 우선순위를 뜻합니다. 애니메이션, 이벤트 처리, UI 갱신 등 사용자와의 상호작용을 하는 작업에 이 Qos를 할당합시다.

  2. userInitiated: 두번째로 높은 우선순위입니다. 빠른 반응 속도가 필요하거나, 유저가 앱에 기대하는 핵심 정보를 로딩할 때 등에 사용합니다.

  3. default: 세번째로 높은 우선 순위이자 기본 값입니다. 앱 초기화 혹은 유저를 대신해 수행하는 작업에 사용합니다.

  4. utility: default보다 한단계 낮은 우선순위입니다. 바로 완료되지 않아도 앱사용에 지장이 없는 부가적인 작업에 사용합니다.

  5. background: 가장 낮은 우선순위입니다. 앱이 백그라운드 상태로 갔을 때 할 작업 등에 사용합니다.

Qos는 시스템에도 힌트를 주지만, 프로그래머들에게도 그 의도를 명확히 한다는 점에서 구분해서 사용하는 것이 좋습니다.