iOS - 核心数据 - 在NSManagedObject子类中使用remove方法后保存失败

时间:2012-05-15 12:59:45

标签: ios core-data nsmanagedobject

概述:

  1. 我使用提供的删除方法删除NSManagedObject 自动生成的NSManagedObject子类
  2. 然后我尝试保存数据库
  3. 数据库保存失败。
  4.  - (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个表(实体),即“员工”和“部门”
    • 一个部门可以包含多个员工
    • 一名员工只能属于一个部门

    关系详情:

    • 从“员工”到“部门”的关系是一对一关系,称为“部门”。删除规则为Nullify
    • 从“部门”到“员工”的关系是多对一关系,被称为“员工”。删除规则是Cascade

    问题:

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

    (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. 我的关系(反向,删除规则等)是否设置正确?
    4. 答案:

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

2 个答案:

答案 0 :(得分:4)

我打赌你没有保存你的背景。删除对象时,只会在下次保存上下文时将其标记为删除。

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

修改

啊......我看到你正在使用UIManagedDocument(我可以通过你正在使用的保存电话告诉我)。在处理CoreData时,您应该在问题中提供特别是的完整详细信息,因为它有很多旋钮和交互。

好的,首先,UIManagedDocument是一个"无需保存的"建筑。使用UIManangedDocument时,不应该求助于调用saveToURL。

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

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

文档说明如果你想保存,你需要做两件事之一。

  1. 使用UndoManager并让它标记为脏东西
  2. 调用[document updateChangeCount:UIDocumentChangeDone];
  3. 现在,实际的保存将在未来的一些破坏时间发生。但是,有些事情(比如进入后台)会触发保存。

    同样,你怎么知道数据没有保存?

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

    添加

    [self.database updateChangeCount:UIDocumentChangeDone];
    

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

    修改

    不幸的是,如果您收到错误,后台保存可能会无声地失败。因此,您应该关注状态更改通知,因为这是您获得sn错误的唯一通知。

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

    我注册了状态更改通知,并提供了一个简单的UIManagedDocument子类,其中包含handleError:userInteractionPermitted:重写以记录错误。看看它告诉你什么。希望它会引导你为什么不进行保存。

    另外,不要忘记你必须等待保存。

    最后,如果您想查看CoreData在SQL级别上所做的事情,请在命令行选项中设置debugging(-com.apple.CoreData.SQLDebug 1)以查看SQLLite语句。

答案 1 :(得分:2)

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

我没有使用自动生成的移除方法,而是使用NSManagedObjectContext的{​​{1}}方法

<强>修正:

deleteObject