trying to save NSManagedObjectContext not working

跟風遠走 提交于 2021-02-18 22:09:05

问题


I have been trying to figure out this problem for 2 days now. I keep getting an error when I try 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 though, this appears in the console:

"CoreData: error: Mutating a managed object 0x10935d4c0 (0x10935d420) after it has been removed from its context."

And this:

Save did not complete successfully. Error: (null)

I can't figure out why this is happening, or why the error is "null".


回答1:


Given this error:

2015-07-06 06:15:05.124 xxx[3609:796500] CoreData: error: Mutating a managed object 0x17423d3e0 (0x1740d0450) after it has been removed from its context.

Found:

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

Initial Results:

  1. d: init(modelName:):1
  2. mext: findInStore(_:):1
  3. mext: findInStore(_:sortDescriptors:predicate:):1
  4. mext: NSManagedObject:1
  5. d:context DataStore:1
  6. d:persistentStoreCoordinator :1
  7. d: managedObjectModel:1
  8. d: applicationDocumentsDirectory:1
  9. mext: createInStore(_:):1
  10. mext: NSManagedObject:2
  11. d:context DataStore:2

Final Results

  1. db: init(modelName:databaseName:):1
  2. d: init(modelName:):1
  3. mext: findInStore(_:):1
  4. mext: findInStore(_:sortDescriptors:predicate:):1
  5. mext: NSManagedObject:1
  6. d:managedObjectContext managedObjectContext:1
  7. d:persistentStoreCoordinator :1
  8. d: managedObjectModel:1
  9. d: applicationDocumentsDirectory:1

Recommendation:

For others having this problem, I recommend a close inspection of your Core Data Stack's initialization sequence. A context may be created twice or the managed object might be getting deleted.




回答2:


There is another way to provoke the "CoreData: error: Mutating a managed object ... after it has been removed from its context." message.

  • If you have a multiple layer core data stack
  • You hold a strong reference to a managed object in the foreground
  • A background thread updates that same core data object

When the update bubbles up to the foreground thread it invalidates your object. You need to detect that and retrieve the new version.

Hold a weak reference in a cache object. Then write a getter that checks that cache object for nil and retrieves the 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 could just retrieve the object every time in the getter.




回答3:


This error can also result when your moc is mistakenly a weak reference and is garbage collected before you get a chance to use it. Don't ask me how I know this...



来源:https://stackoverflow.com/questions/24965458/trying-to-save-nsmanagedobjectcontext-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!