티스토리 뷰

앱을 개발하다 보면 이런 상황을 자주 만나게 된다.

  • 네트워크 요청을 보냈는데 응답이 느려서 UI가 멈춘다.
  • 이미지 로딩이 오래 걸려서 스크롤이 끊긴다.
  • 데이터 연산이 많아서 앱이 버벅인다.

이런 문제를 해결하려면 비동기 처리를 해야 하는데, 이때 가장 많이 사용하는 게 바로 GCD(Grand Central Dispatch) 다. iOS에서 멀티스레딩을 쉽게 다룰 수 있도록 도와주는 API다.

이번 글에서는 GCD가 뭔지, 어떻게 동작하는지, 그리고 실무에서 어떻게 활용할 수 있는지 알아보자!


GCD(Grand Central Dispatch)란?

GCD는 iOS에서 멀티스레딩을 쉽게 다룰 수 있도록 도와주는 프레임워크다. 쉽게 말해, 실행할 작업을 큐(queue)에 넣으면 적절한 시점에 실행해 준다.

"멀티스레딩이 왜 필요할까?"

앱에서 모든 작업을 메인 스레드에서 실행하면 화면이 멈추거나 버벅거릴 수 있다.
GCD를 사용하면 무거운 작업을 백그라운드에서 실행하고, UI 업데이트는 메인 스레드에서 처리할 수 있다.


DispatchQueue란?

GCD에서 작업을 실행하는 공간이 큐(DispatchQueue) 다.
여러 개의 작업을 큐에 넣으면 순서대로 실행하거나 동시에 실행할 수 있다.

 

큐의 종류

큐 종류 실행 방식 특징

큐 종류 실행 방식 특징
직렬 큐(Serial Queue) 순차 실행 한 번에 하나의 작업만 실행
동시 큐(Concurrent Queue) 동시 실행 여러 개의 작업을 동시에 실행

직렬 큐는?
→ "한 작업이 끝나야 다음 작업을 실행하는 방식"

동시 큐는?
→ "여러 작업을 동시에 실행하지만, 언제 끝날지는 알 수 없는 방식"

 

직렬 큐 예제

let serialQueue = DispatchQueue(label: "com.example.serialQueue")

serialQueue.async {
    print("Task 1 시작")
    sleep(2) // 2초 대기
    print("Task 1 완료")
}

serialQueue.async {
    print("Task 2 시작")
    sleep(1) // 1초 대기
    print("Task 2 완료")
}

출력 결과:

Task 1 시작  
(2초 대기)  
Task 1 완료  
Task 2 시작  
(1초 대기)  
Task 2 완료  

하나씩 순차적으로 실행됨


동시 큐 예제

let concurrentQueue = DispatchQueue(label: "com.example.concurrentQueue", attributes: .concurrent)

concurrentQueue.async {
    print("Task 1 시작")
    sleep(2)
    print("Task 1 완료")
}

concurrentQueue.async {
    print("Task 2 시작")
    sleep(1)
    print("Task 2 완료")
}

출력 결과 (실행할 때마다 달라질 수 있음):

Task 1 시작  
Task 2 시작  
Task 2 완료  
Task 1 완료  

여러 작업이 동시에 실행됨


DispatchQueue를 활용하는 방법

1. 메인 스레드에서 UI 업데이트

네트워크 요청을 보낸 후 UI를 업데이트할 때는 반드시 메인 스레드에서 실행해야 한다.

DispatchQueue.global().async {
    let image = downloadImage() // 백그라운드에서 이미지 다운로드

    DispatchQueue.main.async {
        imageView.image = image // UI 업데이트 (메인 스레드에서 실행)
    }
}

백그라운드에서 이미지를 다운로드한 후, 메인 스레드에서 UI를 업데이트!

 

2. 작업을 일정 시간 후에 실행하기 (딜레이 처리)

DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
    print("3초 후 실행됨")
}

3초 후에 코드가 실행됨

 

3. 특정 작업이 끝난 후 실행하기 (그룹 작업)

여러 개의 작업이 끝난 후 특정 코드를 실행해야 할 때는 DispatchGroup을 사용할 수 있다.

let group = DispatchGroup()
let queue = DispatchQueue.global()

group.enter()
queue.async {
    sleep(2)
    print("작업 1 완료")
    group.leave()
}

group.enter()
queue.async {
    sleep(1)
    print("작업 2 완료")
    group.leave()
}

group.notify(queue: .main) {
    print("모든 작업 완료 후 실행됨")
}

모든 비동기 작업이 끝난 후 실행됨


GCD를 사용할 때 주의할 점

  1. UI 업데이트는 항상 메인 스레드에서!
    → 백그라운드 작업을 실행한 후 DispatchQueue.main.async로 UI를 업데이트해야 한다.
  2. Deadlock(교착 상태)을 조심하자
    sync를 잘못 사용하면 스레드가 멈출 수 있다.
    sync는 현재 스레드에서 실행을 기다리므로, 같은 큐에서 호출하면 문제가 발생한다.
let queue = DispatchQueue(label: "com.example.queue")

queue.sync {
    print("작업 1 시작")
    queue.sync { // 같은 큐에서 sync 호출 → Deadlock 발생!
        print("작업 2 시작")
    }
    print("작업 1 완료")
}

⚠️ 실행하면 앱이 멈춰버림!


정리

GCD는 iOS에서 비동기 작업을 쉽게 처리할 수 있도록 도와주는 필수적인 도구다.
이번 글에서 다룬 내용을 정리해 보면:

 

✅ DispatchQueue를 사용해 작업을 백그라운드에서 실행할 수 있다.
✅ 메인 스레드에서 UI를 업데이트해야 한다.
✅ 직렬 큐는 순차 실행, 동시 큐는 여러 작업을 동시에 실행한다.
✅ async, sync, DispatchGroup 등을 활용해 다양한 비동기 작업을 제어할 수 있다.

 

GCD를 잘 활용하면 앱이 더 빠르고 부드럽게 동작할 수 있다.

언급한 내용 말고도 다양한 활용법과 기능이 있다

멀티스레딩을 깊게 이해하려면 앞으로도 꾸준한 공부가 필요해 보인다

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
글 보관함