iosswiftcore-datacorestore

CoreStore create object in context without saving to database


I want to solve next problem:

I would like to work with some NSManagedObject in context and change some properties in runtime, but without telling SQLite about any changes in it.

I just want to save NSManagedObject to database when I hit save button or similar.

As I found out from source code demo we need to use beginUnsafe for this purposes (maybe I am wrong)

func unstoredWorkout() -> WorkoutEntity {

    let transaction = CoreStore.beginUnsafe()
    let workout = transaction.create(Into<WorkoutEntity>())

    return workout
}

let workout = unstoredWorkout()
workout.muscles = []

Now when I try to update workout.muscles = [] app crashes with error:

error: Mutating a managed object 0x600003f68b60 <x-coredata://C00A3E74-AC3F-47FD-B656-CA0ECA02832F/WorkoutEntity/tC3921DAE-BA43-45CB-8271-079CC0E4821D82> (0x600001c2da90) after it has been removed from its context.

My question how we can create object without saving it and how we can save it then when we modify some properties and avoid this crash as well.


Solution

  • The reason for the crash is that your transaction only lives in your unstoredWorkout() method, so it calles deinit, which resets the context (and deletes all unsaved objects). You have to retain that unsafe transaction somewhere to keep your object alive - such as in the viewcontroller that will eventually save the changes.

    But I would rather encourage you to think about that if you really want to do that. You might run into other synchronization issues with various context or other async transactions alive, like when API calls are involved.