【问题标题】:trying to save NSManagedObjectContext not working试图保存 NSManagedObjectContext 不起作用
【发布时间】:2014-09-17 21:10:44
【问题描述】:

我已经尝试解决这个问题 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”。

【问题讨论】:

  • 您从其上下文中删除了一个对象并试图更改它。您不能更改孤立对象。先解决这个问题,然后我们才能整理存档。
  • 如果这是一个愚蠢的问题,我很抱歉,但我无法检测到我在哪里做的。你在这段代码中看到了吗?
  • 嗯……我建议在你的项目中搜索对deleteObject:的调用。
  • 感谢您的帮助,但我想通了。每次我访问它时,我的 managedObjectContext 都会被删除,然后被替换。很难解释,但我只是编码错误
  • 如果您认为对他人有帮助,请添加您自己的答案或删除问题;-)

标签: ios core-data nsmanagedobjectcontext


【解决方案1】:

还有另一种方法可以引发“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 中检索对象。

【讨论】:

  • 谢谢。我使用的是临时上下文,并将保存对象的变量更改为weak,修复了这个警告,现在它可以正确保存了。
【解决方案2】:

当您的 moc 错误地是弱引用并且在您有机会使用它之前被垃圾收集时,也会导致此错误。别问我怎么知道的……

【讨论】:

    【解决方案3】:

    鉴于此错误:

    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.

    找到:

    就我而言;初始化序列的跟踪(使用断点和日志消息 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

    最终结果

    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

    推荐:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 2013-07-14
      • 2011-07-26
      • 1970-01-01
      相关资源
      最近更新 更多