GCD에서 Background Thread에서 UI를 업데이트하면 발생하는 문제

sonny·2025년 2월 27일
0

TIL

목록 보기
140/140

GCD(Grand Central Dispatch)를 사용하면 멀티스레딩을 쉽게 구현할 수 있다. 하지만 UIKit의 UI 업데이트는 반드시 메인 스레드에서 실행해야 한다. 만약 background thread에서 UI를 업데이트하면 어떤 문제가 발생하는지 알아보자.


1. UI 업데이트는 메인 스레드에서만 가능

UIKit은 UI 관련 작업(뷰 업데이트, 레이아웃 변경 등)메인 스레드(Main Thread) 에서 실행해야 한다.
이 규칙을 어기고 background thread에서 UI를 변경하면 예측할 수 없는 동작이 발생하거나 앱이 크래시할 수 있다.

문제 코드 (잘못된 예제)

DispatchQueue.global(qos: .background).async {
    // 백그라운드 스레드에서 UI 업데이트 시도 (잘못된 코드)
    myLabel.text = "Updated Text"
}

위 코드를 실행하면 앱이 바로 크래시가 나지 않을 수도 있다. 하지만 레이아웃이 깨지거나, UI가 정상적으로 변경되지 않는 버그가 발생할 가능성이 크다.


2. 왜 background thread에서 UI를 업데이트하면 안 될까?

UIKit의 내부 구조를 보면, UI 관련 작업(뷰 변경, 애니메이션, 터치 이벤트 처리 등)은 단일 스레드에서 실행되어야 한다.
만약 여러 개의 스레드가 동시에 UI를 변경한다면 Race Condition(경쟁 상태) 가 발생하여 예측할 수 없는 동작이 일어날 수 있다.

Race Condition이란?

둘 이상의 스레드가 동시에 같은 리소스를 변경하려고 할 때, 실행 순서에 따라 결과가 달라지는 문제를 의미한다.
UI 변경 작업이 메인 스레드가 아닌 다른 스레드에서 실행되면, 동기화되지 않은 상태에서 UI를 조작하게 되어 충돌이나 크래시가 발생할 수 있다.


3. 올바른 UI 업데이트 방법 (메인 스레드에서 실행하기)

GCD를 사용할 때, UI 업데이트가 필요하면 메인 스레드에서 실행되도록 DispatchQueue.main.async를 사용해야 한다.

정상적인 코드 (올바른 UI 업데이트)

DispatchQueue.global(qos: .background).async {
    let data = fetchData() // 백그라운드에서 데이터 가져오기

    DispatchQueue.main.async {
        myLabel.text = data // UI 업데이트는 메인 스레드에서 수행
    }
}

설명

  1. DispatchQueue.global(qos: .background).async백그라운드 스레드에서 데이터를 가져온다.
  2. DispatchQueue.main.async메인 스레드에서 UI를 업데이트한다.

이렇게 하면 UI 업데이트가 안전하게 실행되며, 레이스 컨디션을 방지할 수 있다.


4. 결론

✅ UIKit은 UI 변경 작업을 오직 메인 스레드에서 실행해야 한다.
✅ Background thread에서 UI를 업데이트하면 레이아웃 깨짐, 예측 불가능한 동작, 크래시가 발생할 수 있다.
✅ UI 변경이 필요하면 DispatchQueue.main.async를 사용하여 메인 스레드에서 실행해야 한다.

📌 한 줄 요약

"UIKit의 모든 UI 업데이트는 메인 스레드에서 실행해야 하며, 백그라운드 작업 후 UI 변경이 필요하면 DispatchQueue.main.async를 사용해야 한다."

profile
iOS 좋아. swift 좋아.

2개의 댓글

comment-user-thumbnail
2025년 3월 3일

sonny 정말 리스펙! 자랑스러운 TIL 상 축하드려요 🎉

1개의 답글

관련 채용 정보