2

概述:

  1. 我使用自动生成的 NSManagedObject 子类中提供的删除方法删除 NSManagedObject
  2. 然后我尝试保存数据库
  3. 数据库保存不成功。

.

 - (void)removeEmployees:(NSSet *)values; //Auto generated method in Department.h

但是使用 add 方法添加 NSManagedObject 可以成功保存数据库

 - (void)addEmployeesObject:(Employee *)value; //Auto generated method in Department.h - works fine

注意:我使用的是 XCode 生成的 NSManagedObject 子类。

实体详情:

  • 我有 2 个表(实体),即“员工”和“部门”
  • 一个部门可以包含多名员工
  • 一名员工只能属于一个部门

关系详情:

  • 从“Employee”到“Department”的关系是一对一的关系,称为“whichDepartment”。删除规则为无效
  • 从“部门”到“员工”的关系是多对一的关系,称为“员工”。删除规则是级联

问题:

“部门”类有一个方法调用如下,我使用这个方法后,数据库保存不成功

(void)removeEmployees:(NSSet *)values; //Auto generated method in Department.h //does not work

用于删除的代码:

- (void) removeEmployeesHavingAgeAsZeroWithDepartment: (Department*) department

{
    NSMutableSet *employeesSetToBeRemoved = [[NSMutableSet alloc] init];

    for(Employees *currentEmployee in department.employees)
    {
        if(currentEmployee.age == 0)
        {
            [employeesSetToBeRemoved addObject:currentEmployee];
        }
    }

    [department removeEmployees:employeesSetToBeRemoved]; //causing the problem
}

用于保存数据库的代码

[self.database saveToURL:self.database.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success) 
  {NSLog(@"DB saved");}];

问题:

  1. 为什么使用remove方法后保存数据库不成功?
  2. 我需要实现这个方法吗?目前我没有看到这个方法的任何实现,我只能在头文件中找到它。
  3. 我的关系(反向、删除规则等)是否设置正确?

回答:

  • 请参考 Jody 的回答和评论(5 月 17 日 4:39),很好地解释了如何调试问题并找到根本原因
4

2 回答 2

4

我打赌你没有保存你的上下文。当你删除一个对象时,它只是被标记为在下次保存上下文时被删除。

如果你对每个对象调用 isDeleted,你会得到什么?

编辑

啊...我看到您正在使用 UIManagedDocument (我可以通过您正在使用的保存调用来判断)。你应该在你的问题中提供完整的细节,尤其是在处理 CoreData 时,因为它有很多旋钮和交互。

好的,所以,首先,UIManagedDocument 是一个“无保存”架构。使用 UIManangedDocument 时不应求助于调用 saveToURL。

它会自动将自己保存在后台线程上。但是,您必须告诉它有更新要更改。

另外,你怎么知道它没有保存?我知道这听起来像是一个奇怪的问题,但重要的是要知道你在看什么,以及你是如何确定文档没有保存的。

该文档指出,如果要保存,则需要做两件事之一。

  1. 使用 UndoManager 并让它标记脏东西
  2. 调用 [document updateChangeCount:UIDocumentChangeDone];

现在,实际的保存将在未来某个被破坏的时间发生。但是,有些事情(比如进入后台)会触发保存。

再说一次,你怎么知道数据没有保存?

您是否只是查看托管对象、从 MOC 获取、查看文件?

添加

[self.database updateChangeCount:UIDocumentChangeDone];

在该删除功能结束时,您的数据肯定会被保存。

编辑

不幸的是,如果出现错误,后台保存可能会静默失败。因此,您应该注意状态更改通知,因为这是您将收到的唯一通知,即发生 sn 错误。

虽然您会在状态因错误而改变时收到通知,但您不会收到有关错误原因的详细信息。为此,如果您想要实际的 NSError 详细信息,则必须在 UIManagedDocument 的子类中覆盖 handleError:userInteractionPermitted:。

我将注册状态更改通知并提供 UIManagedDocument 的简单子类,其中 handleError:userInteractionPermitted: 被覆盖以记录错误。看看这告诉你什么。希望它会引导您了解为什么您的保存没有发生。

Also, don't forget that you have to WAIT for the save.

Finally, if you want to see what CoreData is doing at the SQL level, set debugging (-com.apple.CoreData.SQLDebug 1) in command line options to see SQLLite statements.

于 2012-05-15T15:41:45.790 回答
2

经过一番调查,我意识到数据库没有得到保存。

我没有使用自动生成的 remove 方法,而是使用了NSManagedObjectContext'sdeleteObject方法

使固定:

[self.managedObjectContext deleteObject:currentEmployee];
于 2012-05-15T15:39:42.673 回答