Same thing happens to me. Useless stack trace, with EXC_BREAKPOINT in SwiftUI.AsyncRenderer.
What's even worse is that settings the value isn't even an requirement for the crash.
VStack(spacing: 0) {
// ...
}
.onGeometryChange(for: CGRect.self) { proxy in
proxy.frame(in: .local)
} action: { frame in /* do nothing */ }
This crashes too. The mere presence of the onGeometryChange modifier causes a seemingly unavoidable crash.
Even more curiously, this always happen at this exact location, but if I render the same view in another part of my app it works perfectly.
Post
Replies
Boosts
Views
Activity
I believe I now know exactly what's causing this.
I've filed FB14344675 with a detailed description of the problem.
When an @ModelActor is created and later released (for example dropped at the end of a function scope), the model instances fetched by its associated model context can't be meaningfully used anymore.
This behavior is new in iOS 18. I don't know whether iOS 18 now actually resets the background context on deinit, whether iOS 17 somehow kept it alive until all instances were gone, or whether it's something entirely different that caused this regression.
Anyway, the solution is as follows:
Do NOT fetch model instances using a ModelActor-conforming actor, if the actor doesn't outlive the fetched instances.
Instead, keep the actor around. I'm doing this using a @State variable, but I suppose it could also be done by making the actor a singleton.
In the case that the crash is actually indented behavior and model instances aren't supposed to outlive their model context, I'd be very interested in hearing about a proper architectural solution to this problem.
The singleton solution seems the simplest, but it makes two assumptions that I don't like at all: The model context has to be well-known and static.
In my case, this simply doesn't work, because I have two model containers: One for previews with in-memory storage only, and one for development with proper on-disk storage.
Since the "correct" model container is only known at runtime, my actor can't be a singleton. It has to be instantiated with a reference to the model context.
This, however, causes the following problem: The actor can't be created on view creation, because the model container isn't (yet) accessible. I don't see a good solution to this.
This has been my solution so far:
struct MyView: View {
@Environment(\.modelContainer) private var container
@State private var myActor: MyModelActor?
// Use this whenever you need the actor
func getModelActor() -> MyModelActor {
guard let myActor else {
let myActor = MyModelActor(modelContainer: container)
self.myActor = myActor
return myActor
}
return myActor
}
var body: some View {
SomeContent()
}
}
That's a super ugly solution in my opinion, and although it does work, I really wouldn't wanna use this if there's a better way.
Since an Apple engineer said we shouldn't create multiple contexts and use @State variables, etc.:
My model container is created in the App and never recreated anywhere else. I do use a ModelActor though, which is initialized from the context provided by the environment whenever it's needed.
Same issue here.. I've been told to do this and there's no "Call me" button. I even tried it over multiple hours and multiple timezones. It's just not showing up at all. I've emailed them back and asked for clarification, let's see what happens.