试图保存NSManagedObjectContext无法正常工作

时间:2014-07-25 22:28:54

标签: ios core-data nsmanagedobjectcontext

我一直试图解决这个问题2天了。我试图保存时不断收到错误。

//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]);
}

当我运行它时,它会出现在控制台中:

  

" CoreData:错误:将托管对象0x10935d4c0(0x10935d420)从其上下文中删除后进行变更。"

而且:

  

保存未成功完成。错误:(null)

我无法弄清楚为什么会发生这种情况,或者为什么错误是" null"。

3 个答案:

答案 0 :(得分:3)

鉴于此错误:

2015-07-06 06:15:05.124 xxx [3609:796500] CoreData:错误:在从上下文中删除托管对象0x17423d3e0(0x1740d0450)后对其进行变更。

发现:

在我的情况下;一段初始化序列(使用断点和日志消息class_initial:%B:%H )显示我正在创建两次上下文。我的解决方案是简单地将冗余调用重定向到self.managedObjectContext 。我可能会在稍后的时间跟踪并消除冗余逻辑。

初步结果:

  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
  12. 最终结果

    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
    10. <强>建议:

      对于遇到此问题的其他人,我建议仔细检查您的Core Data Stack的初始化序列。可能会创建两次上下文,或者可能会删除托管对象。

答案 1 :(得分:2)

还有另一种方法可以引发“CoreData:错误:在托管对象从其上下文中删除后对托管对象进行变更”。消息。

  • 如果您有多层核心数据堆栈
  • 您在前台
  • 中拥有对托管对象的强引用
  • 后台线程更新相同的核心数据对象

当更新冒泡到前台线程时,它会使您的对象失效。您需要检测并检索新版本。

在缓存对象中保留弱引用。然后编写一个getter,检查该缓存对象是否为nil,并检索该对象的新版本。

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
    }
}

或者,您每次都可以在getter中检索对象。

答案 2 :(得分:1)

如果您的moc错误地是弱引用并且在您有机会使用它之前进行了垃圾收集,也会导致此错误。不要问我怎么知道这个...