Trying to keep NSManagedObjectContext not working

I tried to find out this problem for 2 days. I keep getting an error when trying to save.

//self.data is NSManagedObject. kAppDelegate.moc is the managed object context. self.data = [NSEntityDescription insertNewObjectForEntityForName:@"Data" inManagedObjectContext:kAppDelegate.moc]; [self.data setValue:[NSNumber numberWithBool:NO] forKey:@"isit"]; [self.data setValue:@"" forKey:@"name"]; NSError *error; if(![self.data.managedObjectContext save:&error]) { NSLog(@"Save did not complete successfully. Error: %@", [error localizedDescription]); } 

When I run it, it appears in the console:

"CoreData: error: Mutation of the managed entity 0x10935d4c0 (0x10935d420) after removing it from the context."

And this:

Save failed. Error: (null)

I cannot understand why this is happening, or why the error is "null".

+6
source share
3 answers

Given this error:

2015-07-06 06: 15: 05.124 xxx [3609: 796500] CoreData: error: Mutation of the managed object 0x17423d3e0 (0x1740d0450) after removing it from the context.

Found:

In my case; the trace of the initialization sequence (using breakpoints and the log message class_initial:% B:% H) showed that I created the context twice . My solution was to simply redirect the redundant call to self.managedObjectContext . I can spend time at a later point to track and eliminate redundant logic.

Initial Results:

  • d: init (modelName :): 1
  • mext: findInStore (_ :): 1
  • mext: findInStore (_: sortDescriptors: predicate :): 1
  • mext: NSManagedObject: 1
  • d: context DataStore: 1
  • d: persistentStoreCoordinator: 1
  • d: managedObjectModel: 1
  • d: applicationDocumentsDirectory: 1
  • mext: createInStore (_ :): 1
  • mext: NSManagedObject: 2
  • d: context DataStore: 2

End results

  • db: init (modelName: databaseName :): 1
  • d: init (modelName :): 1
  • mext: findInStore (_ :): 1
  • mext: findInStore (_: sortDescriptors: predicate :): 1
  • mext: NSManagedObject: 1
  • d: managedObjectContext managedObjectContext: 1
  • d: persistentStoreCoordinator: 1
  • d: managedObjectModel: 1
  • d: applicationDocumentsDirectory: 1

Recommendation:

For others having this problem, I recommend that you carefully study the initialization sequence of the Core Data Stack. A context can be created twice, or a managed entity can be deleted.

+1
source

There is another way to provoke "CoreData: error: Mutation of a managed entity ... after it has been removed from the context." message.

  • If you have a multi-layer kernel data stack
  • You keep the link to the managed entity in the foreground
  • Background thread updates the same main data object

When an update bubbles up to the foreground stream, it will invalidate your object. You need to discover this and get a new version.

Hold the weak link in the cache object. Then write a getter that checks this cache object on nil and retrieves a new version of the object.

 weak var cachedObject: NSManagedObject? var object: NSManagedObject { get { objc_sync_enter( self ) defer { objc_sync_exit( self) } guard nil == cachedObject else { return cachedObject! } guard let object = // **** retrieve object here **** fatalError( "managed object does not exist" ) } cachedObject = object return cachedObject! } set { cachedObject = newValue } } 

Or you can just retrieve the object every time in getter.

+1
source

This error can also occur when your moc is mistakenly a weak standard and collects garbage before you can use it. Do not ask me how I know this ...

0
source

Source: https://habr.com/ru/post/972868/


All Articles