I've had a persistent but hard to reliably reproduce issue when using SwiftData with SwiftUI.
Sometimes, when some properties of a SwiftData model object are used in the UI (like the title of a note in a list of notes) and something in the model is modified, the UI stops responding. The modification in the model could be a completely different object and of a different type and could be as simple as toggling a Bool, it could be performed on the main thread from inside a Button's action using the ModelContext from the environment or on a separate thread using a ModelActor. The issue even appears and disappears between builds of the same code.
As an example, this is the kind of code that leads to this issue, though I haven't been able to make a minimal reproduction because of how inconsistently it appears:
@ModelActor
struct NoteModifier {
func append() {
guard let notes = try? modelContext.fetch(FetchDescriptor<Note>()) else { return }
notes.randomElement()!.title.append("ABC")
try? modelContext.save()
}
}
struct ContentView: View {
@Environment(\.modelContext) private var modelContext
@Query private var notes: [Note]
var body: some View {
VStack {
List {
ForEach(notes) { note in
VStack {
Text(note.title)
Text(note.contents)
}
}
}
Button {
Task {
await NoteModifier(modelContainer: modelContext.container).append()
}
} label: {
Text("Bug")
}
}
}
}
When it happens and I try pausing execution, it's locked inside kevent_id in the getter for one of the properties of my model object like this:
In Instruments: