Swift에서 메인 스레드에서 작업을 실행할 때 흔히 사용하는 두 가지 방법이 있습니다
DispatchQueue.main.async {} (Grand Central Dispatch, GCD)
@MainActor (Swift Concurrency)
둘 다 메인 스레드에서 실행을 보장하지만, 작동 방식과 특징이 다릅니다.
1️⃣ DispatchQueue.main.async (GCD)
・즉시 실행되지 않고 메인 스레드의 작업 큐(Queue)에 비동기적으로 추가
・클로저(closure) 단위로 실행되며, Swift Concurrency (async/await)와는 직접적인 관계가 없음
・Objective-C 및 기존 코드와 호환성
DispatchQueue.main.async {
print("이 코드는 메인 스레드에서 실행됨")
}
When
・UI 업데이트 (UIView, UIKit, SwiftUI)
・기존 GCD 기반 비동기 작업을 사용
・Swift 5.5 이전의 코드에서 async/await를 사용하지 않는 경우
2️⃣ @MainActor (Swift Concurrency)
・Swift Concurrency (async/await)와 통합된 방식으로 작동
・함수 또는 전체 타입을 메인 스레드에서 실행하도록 강제
・비동기 함수와 함께 사용할 때 더 안전하게
・컴파일러가 메인 스레드에서 실행해야 하는지 검증 가능
→ 런타임 오류를 줄일 수 있음
@MainActor
func updateUI() {
print("이 함수는 메인 스레드에서 실행됨")
}
Task {
await updateUI() // 자동으로 메인 스레드에서 실행됨
}
클래스/구조체/Actor 전체에 적용
@MainActor
class ViewModel {
var title: String = ""
func updateTitle(newTitle: String) {
title = newTitle
}
}
・ViewModel의 모든 속성과 메서드는 항상 메인 스레드에서 실행
・DispatchQueue.main.async를 사용할 필요 없이 Swift Concurrency와 통합
When
・async/await을 사용하는 환경에서 메인 스레드에서 실행해야 하는 함수를 만들는 경우
・SwiftUI, UIKit 관련 코드에서 컴파일 타임에 메인 스레드 실행을 보장하고 싶을 경우
・Actor 기반 아키텍처를 사용할 경우
기존 GCD기반 API와 Swift Concurrency를 함께 사용??
@MainActor를 사용하는 함수가 있지만, 해당 함수를 GCD 기반의 비동기 코드 내부에서 호출해야 하는 경우, 유용할지도...
자세한 내용은 다음에 정리..