【问题标题】:"Core Data could not fulfill a fault.." error“Core Data 无法完成故障..”错误
【发布时间】:2009-08-12 09:17:37
【问题描述】:

我正在开发一个可可应用程序。我正面临一个严重的问题。

我正在使用以下代码在 Core Data 中删除名为“Directory”的对象的条目:

NSEnumerator *tempDirectories = [[folderArrayController arrangedObjects] objectEnumerator];
id tempDirectory;
while (tempDirectory = [tempDirectories nextObject]){
    [managedObjectContext deleteObject:tempDirectory];
}

但有时在删除后尝试保存时会出现“Core Data 无法完成故障..”之类的异常。我正在使用代码[managedObjectContext save];

我是 Core Data 的新手...期待解决方案。

【问题讨论】:

标签: core-data


【解决方案1】:

这是一个老问题,我一直在努力解决这个问题。所以,认为最好记录下来。

正如上面提到的 Weichsel,the Apple documentation 正确地指出了这个例外的原因。但是,识别保留 NSManagedObject 子类对象的模块是一项繁重的工作(如果文档中引用的第一个原因是问题的根本原因)。

因此,我首先确定了保留 NSManagedObject 的代码部分,而是保留了 NSManagedObjectID 并在需要时从中创建托管对象。类似的讨论可以在 Restkit 文档中找到:

  1. https://github.com/RestKit/RestKit/commit/170060549f44ee5a822ac3e93668dad3b396dc39
  2. https://github.com/RestKit/RestKit/issues/611#issuecomment-4858605

更新了我的 setter 和 getter,以便与其余模块的接口保持不变,而在内部我们现在依赖 NSManagedObjectID 并避免保留 NSManageObject:

-(CSTaskAbstract*)task
{
    CSTaskAbstract *theTask = nil;
    if (self.taskObjectID)
    {
        NSManagedObjectContext *moc = [(CSAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
        // https://github.com/RestKit/RestKit/commit/170060549f44ee5a822ac3e93668dad3b396dc39 &
        // https://github.com/RestKit/RestKit/issues/611#issuecomment-4858605
        NSError *theError = nil;
        NSManagedObject *theObject = [moc existingObjectWithID:self.taskObjectID
                                                         error:&theError];
        if ([theObject isKindOfClass:[CSTaskAbstract class]])
        {
            theTask = (CSTaskAbstract*)theObject;
        }
    }
    return theTask;
}
-(void)setTask:(CSTaskAbstract *)inTask
{
    if (inTask!=self.task)
    {
        // Consequences of retaining a MO when it is detached from its MOC
        [self setTaskObjectID:[inTask objectID]];
    }
}

以上是解决问题的前半部分。我们需要找出应用中可疑部分的依赖关系并消除。

还有一些其他问题,工具 -> 分配是找出哪些模块实际上保留了托管对象的好来源,异常对象将包含有关哪个托管对象造成问题的详细信息,过滤该对象的结果如下图:

我们在一个托管对象上执行 KVO。 KVO 保留观察到的托管对象,因此抛出异常,并且它的回溯不会来自我们的项目。这些很难调试,但猜测工作和跟踪对象的分配和保留释放周期肯定会有所帮助。我删除了 KVO 观察部分,一切都开始工作了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-07
    • 1970-01-01
    • 2011-08-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-04
    • 1970-01-01
    相关资源
    最近更新 更多