GCD(Grand Central Dispatch)를 사용하면 멀티스레딩을 쉽게 구현할 수 있다. 하지만 UIKit의 UI 업데이트는 반드시 메인 스레드에서 실행해야 한다. 만약 background thread에서 UI를 업데이트하면 어떤 문제가 발생하는지 알아보자.
UIKit은 UI 관련 작업(뷰 업데이트, 레이아웃 변경 등)을 메인 스레드(Main Thread) 에서 실행해야 한다.
이 규칙을 어기고 background thread에서 UI를 변경하면 예측할 수 없는 동작이 발생하거나 앱이 크래시할 수 있다.
DispatchQueue.global(qos: .background).async {
// 백그라운드 스레드에서 UI 업데이트 시도 (잘못된 코드)
myLabel.text = "Updated Text"
}
위 코드를 실행하면 앱이 바로 크래시가 나지 않을 수도 있다. 하지만 레이아웃이 깨지거나, UI가 정상적으로 변경되지 않는 버그가 발생할 가능성이 크다.
UIKit의 내부 구조를 보면, UI 관련 작업(뷰 변경, 애니메이션, 터치 이벤트 처리 등)은 단일 스레드에서 실행되어야 한다.
만약 여러 개의 스레드가 동시에 UI를 변경한다면 Race Condition(경쟁 상태) 가 발생하여 예측할 수 없는 동작이 일어날 수 있다.
둘 이상의 스레드가 동시에 같은 리소스를 변경하려고 할 때, 실행 순서에 따라 결과가 달라지는 문제를 의미한다.
UI 변경 작업이 메인 스레드가 아닌 다른 스레드에서 실행되면, 동기화되지 않은 상태에서 UI를 조작하게 되어 충돌이나 크래시가 발생할 수 있다.
GCD를 사용할 때, UI 업데이트가 필요하면 메인 스레드에서 실행되도록 DispatchQueue.main.async
를 사용해야 한다.
DispatchQueue.global(qos: .background).async {
let data = fetchData() // 백그라운드에서 데이터 가져오기
DispatchQueue.main.async {
myLabel.text = data // UI 업데이트는 메인 스레드에서 수행
}
}
DispatchQueue.global(qos: .background).async
→ 백그라운드 스레드에서 데이터를 가져온다. DispatchQueue.main.async
→ 메인 스레드에서 UI를 업데이트한다. 이렇게 하면 UI 업데이트가 안전하게 실행되며, 레이스 컨디션을 방지할 수 있다.
✅ UIKit은 UI 변경 작업을 오직 메인 스레드에서 실행해야 한다.
✅ Background thread에서 UI를 업데이트하면 레이아웃 깨짐, 예측 불가능한 동작, 크래시가 발생할 수 있다.
✅ UI 변경이 필요하면 DispatchQueue.main.async
를 사용하여 메인 스레드에서 실행해야 한다.
"UIKit의 모든 UI 업데이트는 메인 스레드에서 실행해야 하며, 백그라운드 작업 후 UI 변경이 필요하면 DispatchQueue.main.async
를 사용해야 한다."
sonny 정말 리스펙! 자랑스러운 TIL 상 축하드려요 🎉