iOS GCD에 대해서 알아보기 (DispathQueue)

안녕하세요. 마기입니다.
이번 포스팅에서는 멀티스레딩을 위한 API를 알아보겠습니다.

쉽고 편한 멀티 스레딩 처리를 위해 애플은 두가지의 API를 제공하고 있습니다.
GCD(Grand Central Dispatch)라는 C기반의 저수준 API와
NSOperation이라는 Obj-C 기반으로 만들어진 고수준 API가 있습니다.

NSOperation은 GCD보다 약간의 오버헤드가 더 발생되고 느리지만
GCD에서는 직접 처리해야 하는 작업들을 지원 하고 있기 때문에
(KVO관찰, 작업취소 등등) 그정도는 감수하고 사용할만 합니다.

이번 포스팅에서는 부담없이 사용할수 있는 GCD에 대해서 알아보도록 하겠습니다.


DispatchQueue

GCD를 사용하기전에 먼저 알아야 할 클래스가 있습니다.

바로 DispatchQueue라는 클래스인데요.
실제로 해야할 Task를 담아두면 선택된 스레드에서 실행을 해주는 역할을 합니다.

DispatchQueue는 2가지로 종류로 나눌수 있습니다.
Serial Dispatch QueueConcurrent Dispatch Queue입니다.

  • Serial Dispatch Queue
    Serial Queue는 등록된 작업을 한번에 하나씩 차례대로 처리 합니다.
    처리중인 작업이 완료되면 다음 작업을 처리합니다.

  • Concurrent Dispatch Queue
    Concurrent Queue는 등록된 작업을 한번에 하나씩 처리 하지 않고
    여러 작업들을 동시에 처리합니다.

let serialQueue = DispatchQueue(label: "magi82.serial")
print(serialQueue)	// Serial Dispatch Queue

let concurrentQueue = DispatchQueue(label: "magi82.concurrent",
                                    attributes: .concurrent)
print(concurrentQueue)	// Concurrent Dispatch Queue

앱 실행시 시스템에서 기본적으로 2개의 Queue를 만들어 줍니다.
Main QueueGlobal Queue 입니다.

  • Main Queue
    메인 스레드(UI 스레드)에서 사용 되는 Serial Queue 입니다.
    모든 UI 처리는 메인 스레드에서 처리를 해야 합니다.

  • Global Queue
    편의상 사용할수 있게 만들어 놓은 Concurrent Queue 입니다.
    Global Queue는 처리 우선 순위를 위한 qos(Quality of service)
    파라메터를 제공합니다.
    병렬적으로 동시에 처리를 하기때문에 작업 완료의 순서는 정할수 없지만
    우선적으로 일을 처리하게 할수 있습니다.

let mainQueue = DispatchQueue.main
print(mainQueue)	// Main Queue
let globalQueue = DispatchQueue.global(qos: .background)
print(globalQueue)	// Global Queue

QOS 우선순위는 아래와 같습니다.

  1. userInteractive
  2. userInitiated
  3. default
  4. utility
  5. background
  6. unspecified


sync / async

Dispatch Queue는 sync와 async라는 메소드를 가지고 있습니다.
동기, 비동기라는 말을 많이 들어 보셨을 겁니다.

sync는 동기 처리 메소드 입니다.
해당 작업을 처리하는 동안 다음으로 진행되지 않고
계속 머물러 있습니다.
시스템에서 제공하는 Main Queue로 테스트를 해보겠습니다.

DispatchQueue.main.sync {
  print("value: 1")
}
print("value: 2")

// 결과
/*
  value: 1
  value: 2
*/


async는 비동기 처리 메소드 입니다.
sync와는 다르게 처리를 하라고 지시후 다음으로 넘어가 버립니다.
이번에는 시스템에서 제공하는 Global Queue로 테스트를 해보겠습니다.

let globalQueue = DispatchQueue.global(qos: .background)
globalQueue.async {
  print("value: 1")
}
print("value: 2")

// 결과
/*
  value: 2
  value: 1
*/

보통 스레드 처리를 하는 작업들은 시간이 꽤나 걸리는 큰 작업이거나
언제 끝날지 알수 없는 작업에 사용 되는데 (ex: 네트워크, 파일로딩)
작업이 처리 되는동안 아무것도 하지 못하고 멈춰 있으면
앱이 렉이 걸리거나 아무 반응이 없는거처럼 보입니다.

그래서 보통 동기 처리 메소드인 sync는 잘 사용하지 않습니다.

간혹 가다가 오해하는 분들이 계신데
Serial / Concurrent와 sync / async 는 별개 입니다.
직렬인데 비동기 일수도 있고, 병렬인데 동기 일수도 있습니다.
직렬과 병렬은 한번에 하나만 처리하느냐 동시에 여러개 처리하느냐고
동기와 비동기는 처리가 끝날때까지 기다리느냐
지시만하고 다른 처리를 하느냐 입니다.


마치며..

GCD(Grand Central Dispatch)는 앱을 개발하면서
필수로 사용되는 기능입니다. 게다가 간단하고 쉽죠!

하지만 기본 기능이 아닌 지원 하는 여러 고급 기능들을 사용하면
더욱 편리하게 좋은 앱을 개발 할수 있겠죠?
이번 포스팅은 기본적인 내용이지만 다음편에는 조금 더 고급 기능을
알아보도록 하겠습니다.

이상 마기였습니다.

logo



목차

Written on July 9, 2017