When is the StateObject’s autoclosure actually called?

The signature of the StateObject initializer is init(wrappedValue thunk: @autoclosure @escaping () -> ObjectType). The fact that the autoclosure is marked as escaping intrigues me, because that suggests that it could be called after the init has returned.

Why this is interesting is because I have some code where the viewmodel given to the @StateObject depends on an implicitly unwrapped optional type, and I expect the top level initialization of the StateObject to crash because the implicitly unwrapped optional is not ready yet, but to my surprise it did not. My theory is that the autoclosure is being called after the View’s initialization had been called, when the dependency is ready.

heres a minimal sample of that.


class MyDependency: ObservableObject {
    @Published var value = "Hello"
}

class MyViewModel: ObservableObject {
    let dependency: MyDependency
    init(dependency: MyDependency = TestApp.dependency) {
        self.dependency = dependency
        print("✅ ViewModel initialized with dependency:", dependency.value)
    }
}

struct ContentView: View {
    
    @StateObject private var viewModel = MyViewModel() // ⚠️ expected crash?

    var body: some View {
        Text(viewModel.dependency.value).onAppear { TestApp.dependency = Dependency()// dependency is set here after init has been called
        }
    }
}

@main
struct TestApp: App {
    static var dependency: MyDependency!   // not ready yet

    var body: some Scene {
        WindowGroup {
            ContentView()
    }

}```


When is the StateObject’s autoclosure actually called?
 
 
Q