본문 바로가기
감정일기(가칭)

🧩 Swift 6에서 @MainActor와 Singleton(.shared) 접근 시 발생하는 오류 해결하기

by 밤새는 탐험가89 2025. 10. 24.
728x90
SMALL

🧠 들어가며

Swift 6으로 넘어오면서, 동시성(Concurrency) 모델이 한층 더 엄격해졌습니다.
그중에서도 @MainActor가 적용된 객체를 다루다 보면, 아래와 같은 에러를 보신 적 있을 거예요 👇

Main actor-isolated static property 'shared' cannot be referenced from a nonisolated context; this is an error in the Swift 6 language mode

 

이 에러는 Swift 5까지는 경고 수준이었지만,
Swift 6에서는 컴파일 오류(Error) 로 격상되었습니다 ⚠️

 

이번 글에서는 왜 이런 오류가 생기는지,
그리고 실제 실무에서 안전하게 해결하는 방법을 정리해볼게요.


🚧 문제 상황

아래와 같은 코드가 있다고 가정해봅시다 👇

@MainActor
final class DiaryStore {
    static let shared = DiaryStore()
}

@MainActor
final class HomeViewModel: ObservableObject {
    private let store: DiaryStore

    init(store: DiaryStore = DiaryStore.shared) {  // ⚠️ 여기서 에러 발생!
        self.store = store
    }
}

 

Swift 6에서는 컴파일러가 이렇게 불평합니다:

❌ “Main actor-isolated static property 'shared' cannot be referenced from a nonisolated context.”


🔍 에러의 원인

핵심은 initializer의 default parameter(기본 매개변수) 평가 시점에 있습니다.

 

Swift 컴파일러는 init()의 기본값을 평가할 때,
아직 그 init이 MainActor 문맥으로 진입하지 않았다고 간주합니다.

init(store: DiaryStore = DiaryStore.shared)
 

이 시점의 DiaryStore.shared 접근은

MainActor에 속한 객체를 비격리(nonisolated) 문맥에서 접근하려는 시도”
로 간주되어 에러가 납니다.


💡 쉽게 말해서

- @MainActor 클래스 내부의 코드 → 메인 스레드 전용 (UI 스레드)

- init()의 기본 매개변수 → “아직 어디에도 속하지 않은 상태(nonisolated)”

- 그래서 DiaryStore.shared 같은 MainActor 전용 속성에 접근이 불가능한 거예요.

 

이 시점에서 DiaryStore.shared에 접근하려 하면,
“이건 메인 액터 객체야, 근데 아직 메인 액터로 진입 안했잖아?” 라고 컴파일러가 막는 거예요.


✅ 해결 방법

🥇기본값을 생성자 내부에서 처리하기

가장 안전하고 Swift 6에서 완벽하게 호환되는 방식입니다 👇

@MainActor
final class HomeViewModel: ObservableObject {
    private let store: DiaryStore

    init(store: DiaryStore? = nil) {
        self.store = store ?? DiaryStore.shared  // ✅ 안전하게 MainActor에서 접근
    }
}

 

📌 이유:


init 본문 내부는 이미 MainActor 문맥이므로,
이 시점의 .shared 접근은 안전하게 허용됩니다.

 

➡️ Swift 6에서도 완벽하게 통과됩니다.


✨ 결론

“Swift 6에서는 @MainActor 객체를 initializer 기본값에서 직접 접근하면 안 된다.
대신 생성자 본문에서 안전하게 대입하는 것이 정석이다.”

728x90
LIST