iOS 18 strange SwiftData fatal error

Hey developers! I updated to Xcode 16 and iOS 18. I wanted to publish my first iOS 18 update but I keep getting a very strange error after building and launching the app: "Fatal error: This model instance was destroyed by calling ModelContext.reset and is no longer usable." (I haven't changed anything regarding swift data and I never call ModelContext.reset)

This error happens only after building. When I close the app and open it again (without running it through Xcode) the app never crashes and all the data is still there. I couldn't find much bout this error online. Is anyone experiencing the same?

I wonder if this is a bug in Xcode 16 or there is something wrong with my code. I also wonder if I can safely publish my update to App Store, since the error only happens after building. Thank you!

Answered by DTS Engineer in 805271022

The error seems to be the same as what was discussed in the iOS 18 SwiftData ModelContext reset post. You might take a look to see if that helps.

The error typically happens when you try to access a model instance after the associated model container is (unintentionally) released. You can review your code to see if that is your case, and if yes, avoid that.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Accepted Answer

The error seems to be the same as what was discussed in the iOS 18 SwiftData ModelContext reset post. You might take a look to see if that helps.

The error typically happens when you try to access a model instance after the associated model container is (unintentionally) released. You can review your code to see if that is your case, and if yes, avoid that.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

I can confirm that changing the code I replied with earlier, to the following code fixes the problem:

var modelContainer: ModelContainer?
    init() {
        self.modelContainer = try? ModelContainer(for: Event.self)
    }
    @MainActor
    func fetchEvents() -> [Event] {
        guard let modelContainer = modelContainer else {
            return []
        }
        
        let descriptor = FetchDescriptor<Event>(sortBy: [SortDescriptor(\.dateCreated, order: .reverse)])
        guard let events = try? modelContainer.mainContext.fetch(descriptor) else {
            return []
        }
        
        return events
    }

Yeah, the code you provided in your comment creates the model container and holds it with a local variable, which is released after fetchEvents is done, which triggers the error when you try to access the events.

Your new code seems to hold the model container with a member variable, whose life cycle is the same as the object that owns the variable. In case you don't release the object, the model container will be there.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

iOS 18 strange SwiftData fatal error
 
 
Q