Menu
Menu
Posts List
  1. ✅ 1. GCD란?
  2. ✅ 2. GCD의 기본 개념
    1. 🔹 (1) Dispatch Queue (디스패치 큐)
    2. 🔹 (2) Sync vs Async (동기 vs 비동기)
  3. ✅ 3. GCD 사용법 (코드 예제 포함)
    1. 🔹 (1) Main Queue (UI 관련 작업)
    2. 🔹 (2) Global Queue (백그라운드 작업)
    3. 🔹 (3) Custom Queue (사용자 정의 직렬 큐 & 동시 큐)
    4. 🔹 (4) DispatchGroup (작업 그룹)
    5. 🔹 (5) DispatchWorkItem (작업 취소)
  4. ✅ 4. GCD 활용 예제 (실무 적용)
    1. 🔸 (1) 비동기 네트워크 요청 & 이미지 로드
    2. 🔸 (2) Heavy Task + UI 업데이트
  5. ✅ 5. GCD에서 주의할 점
  6. 🎯 정리

GCD

1. GCD란?

GCD(Grand Central Dispatch)iOS의 멀티스레딩 및 비동기 처리를 담당하는 프레임워크다.

💡 “멀티스레드 프로그래밍을 쉽고 효율적으로 수행할 수 있도록 설계된 API”

📌 GCD의 주요 특징

  • 멀티스레딩 지원 (메인 스레드에서 작업을 분리하여 백그라운드에서 실행)
  • 큐 기반(Task Queue) 으로 동작
  • 시스템이 스레드를 자동 관리 (최적화됨)
  • 동기(Synchronous) 및 비동기(Asynchronous) 실행 가능

2. GCD의 기본 개념

GCD는 크게 큐(Queue)와 작업(Work Item) 으로 구성된다.

🔹 (1) Dispatch Queue (디스패치 큐)

GCD에서는 작업을 큐(Queue)에 넣고 실행하며, 큐의 종류는 아래와 같이 나뉜다.

큐 종류 설명
Main Queue (메인 큐) UI 업데이트와 관련된 작업 실행 (⚠️ UI 업데이트는 반드시 메인 큐에서 실행)
Global Queue (글로벌 큐) 우선순위가 다른 여러 개의 시스템 제공 백그라운드 큐
Custom Queue (사용자 정의 큐) 개발자가 직접 만든 큐 (Serial 또는 Concurrent 지정 가능)

📌 큐의 실행 방식 (큐의 동작 방식에 따라 실행 방식이 달라짐)

실행 방식 설명
Serial Queue (직렬 큐) 한 번에 하나의 작업만 실행 (FIFO)
Concurrent Queue (동시 큐) 여러 작업을 동시에 실행

🔹 (2) Sync vs Async (동기 vs 비동기)

동기(sync)와 비동기(async)의 차이점은?

  • Sync (동기 실행): 현재 작업이 끝날 때까지 다음 작업을 실행하지 않음 (Blocking)
  • Async (비동기 실행): 현재 작업과 관계없이 다음 작업을 바로 실행 (Non-Blocking)

📌 비교 예시

1
2
3
4
5
6
7
8
9
10

DispatchQueue.global().sync {
print("Sync 실행 1")
}
print("Sync 실행 2")

DispatchQueue.global().async {
print("Async 실행 1")
}
print("Async 실행 2")

실행 결과 (예상)

1
2
3
4
Sync 실행 1
Sync 실행 2
Async 실행 2
Async 실행 1

Sync는 실행이 완료될 때까지 기다리지만, Async는 기다리지 않음


3. GCD 사용법 (코드 예제 포함)

🔹 (1) Main Queue (UI 관련 작업)

1
2
3
4
DispatchQueue.main.async {
// UI 업데이트는 반드시 메인 큐에서 실행해야 함
self.label.text = "Hello, GCD!"
}

DispatchQueue.main.async 를 사용하여 비동기적으로 UI 업데이트 수행


🔹 (2) Global Queue (백그라운드 작업)

1
2
3
4
5
6
7
DispatchQueue.global().async {
let image = self.loadImage() // 백그라운드에서 이미지 다운로드

DispatchQueue.main.async {
self.imageView.image = image // UI 업데이트는 메인 큐에서 실행
}
}

이미지 다운로드 같은 무거운 작업을 글로벌 큐에서 실행한 후, UI 업데이트는 메인 큐에서 실행


🔹 (3) Custom Queue (사용자 정의 직렬 큐 & 동시 큐)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 직렬 큐 (Serial Queue)
let serialQueue = DispatchQueue(label: "com.example.serialQueue")
serialQueue.async {
print("Task 1")
}
serialQueue.async {
print("Task 2")
}

// 동시 큐 (Concurrent Queue)
let concurrentQueue = DispatchQueue(label: "com.example.concurrentQueue", attributes: .concurrent)
concurrentQueue.async {
print("Concurrent Task 1")
}
concurrentQueue.async {
print("Concurrent Task 2")
}

직렬 큐는 작업을 순차적으로 실행, 동시 큐는 작업을 동시에 실행


🔹 (4) DispatchGroup (작업 그룹)

여러 개의 비동기 작업이 모두 완료된 후 특정 코드를 실행해야 할 때 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
let group = DispatchGroup()

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

group.enter()
DispatchQueue.global().async {
print("작업 2 시작")
sleep(3)
print("작업 2 완료")
group.leave()
}

group.notify(queue: DispatchQueue.main) {
print("모든 작업 완료")
}

실행 결과

1
2
3
4
5
작업 1 시작
작업 2 시작
작업 1 완료
작업 2 완료
모든 작업 완료

여러 작업을 실행하고, 모든 작업이 끝난 후 특정 코드를 실행할 때 사용


🔹 (5) DispatchWorkItem (작업 취소)

1
2
3
4
5
6
7
8
9
10
let workItem = DispatchWorkItem {
print("작업 실행 중...")
}

let queue = DispatchQueue.global()
queue.async(execute: workItem)

// 작업을 취소할 수도 있음
workItem.cancel()

DispatchWorkItem.cancel() 을 사용하면 작업 실행 전에 취소 가능


4. GCD 활용 예제 (실무 적용)

🔸 (1) 비동기 네트워크 요청 & 이미지 로드

1
2
3
4
5
6
7
8
9
10
11
12
func loadImage(from url: String) {
DispatchQueue.global().async {
if let url = URL(string: url),
let data = try? Data(contentsOf: url),
let image = UIImage(data: data) {
DispatchQueue.main.async {
self.imageView.image = image
}
}
}
}

이미지를 비동기적으로 다운로드하고, 완료 후 메인 큐에서 UI 업데이트


🔸 (2) Heavy Task + UI 업데이트

1
2
3
4
5
6
7
8
DispatchQueue.global(qos: .userInitiated).async {
let processedData = heavyProcessingTask()

DispatchQueue.main.async {
self.updateUI(with: processedData)
}
}

백그라운드에서 무거운 작업을 실행한 후, UI 업데이트는 메인 큐에서 수행


5. GCD에서 주의할 점

🚨 주의해야 할 점

  1. UI 업데이트는 반드시 메인 큐에서 실행해야 함
  2. 백그라운드 작업에서 너무 많은 동시 작업을 실행하면 성능 저하 발생 가능
  3. 동기(sync)로 메인 큐를 호출하면 데드락(Deadlock) 발생 가능

🚨 데드락(Deadlock) 발생 예시 (절대 사용하면 안 됨!)

1
2
3
4
DispatchQueue.main.sync {
print("메인 큐 동기 실행") // ❌ 데드락 발생 (Main Thread가 멈춤)
}

🔥 DispatchQueue.main.sync 는 사용하면 안 됨!


🎯 정리

✔️ GCD는 iOS에서 멀티스레드 및 비동기 처리를 위한 핵심 API

✔️ DispatchQueue는 메인 큐, 글로벌 큐, 커스텀 큐로 나뉨

✔️ sync(동기 실행) vs async(비동기 실행)의 차이 이해하기

✔️ UI 업데이트는 반드시 DispatchQueue.main.async에서 실행해야 함

✔️ GCD를 활용하면 성능을 최적화하면서도 부드러운 사용자 경험 제공 가능