Today I Learn

싱글톤 초기화 시점에 따른 Main Thread 오류 해결

Goniii 2025. 4. 23. 20:05

MVVM 구조의 환율 계산 앱에서, ViewModel의 책임을 분리하기 위해 싱글톤으로 ExchangeRateRepository를 만들어 CoreData와 Network를 관리하던 중 음과 같은 오류가 발생했다

Main Thread Checker: UI API called on a background thread: -[UIApplication delegate]

 

오류 원인

CoreData에 접근하기 위해서는 AppDelegate에 선언한 persistentContainer에 접근해야 했고, Repository Init() 내부에서 AppDelegate에 접근했지만, 위와 같은 오류가 난 것이다

private init() {
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    self.coreData = CurrencyCoreData(container: appDelegate.persistentContainer)
}

이 오류는 UIApplication Delegate는 메인스레드에서 호출되어야 하는데 백그라운드 스레드에서 호출되었다는 것이다

이 에러가 발생한 이유는 바로 싱글톤의 Init 시점이 원인이었다. 싱글톤은 처음 호출되는 시점에 Init()이 실행되며 초기화되기 때문에, 비동기 Task 내부에서 shared를 처음 호출하면 초기화가 백그라운드 스레드에서 일어나며 오류가 발생한 것이다

 

따라서 싱글턴의 처음 호출 시점을 AppDelegate에서 미리 호출해두어 이 오류를 해결했다

 

✅ AppDelegate에서 싱글톤 강제 초기화

UIApplication.shared.delegate 접근은 반드시 메인 스레드에서 이루어져야 하므로, AppDelegate의 application(_:didFinishLaunchingWithOptions:)에서 싱글톤을 강제로 초기화하여 해결했다

func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
    _ = ExchangeRateRepository.shared // 메인 스레드에서 강제 초기화
    return true
}