“核心数据无法解决错误......”错误

时间:2009-08-12 09:17:37

标签: core-data

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

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

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

但有时在删除后尝试保存时会发生类似“核心数据无法解决故障...”的异常。我使用的是代码[managedObjectContext save];

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

1 个答案:

答案 0 :(得分:4)

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

正如上面提到的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
  3. 更新了我的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]];
        }
    }
    

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

    还有一些其他问题,工具 - >分配是查找哪些模块实际保留托管对象的好资源,异常对象将详细说明哪个托管对象正在创建问题,过滤该对象的结果,如下所示:

    Instruments - Allocations

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