iOS - 核心数据 - NSManagedObjectContext - 不确定它是否已保存

时间:2012-04-17 03:19:05

标签: ios core-data nsmanagedobjectcontext

概述

  • 我有一个iOS项目,我正在使用Core数据
  • 我正在插入一个对象,然后我想保存它。
  • 我不确定保存是否有效。
  • 当应用程序进入后台时,保存似乎正常工作
  • 使用模拟器时,如果单击Xco​​de上的“停止”按钮,则保存似乎不起作用。

问题

  1. 保存实际发生了吗?
  2. 我遇到问题是因为我创建了一个基于视图的应用程序(核心数据复选框不可用)?
  3. 遵循的步骤

    • 我正在使用模拟器进行测试。
    • 插入一个对象(代码在下一节中)
    • 保存插入的对象(代码在下一节中)
    • 我按下Xcode上的停止按钮以停止运行应用程序

    输出已注意

    setBeforeSave.count = 1
    setAfterSave.count = 0
    
    • 保存之前,NSManagedObjectContext方法insertedObjects会返回1个对象
    • 保存之前,NSManagedObjectContext方法insertedObjects返回0个对象
    • 当按下Xcode停止按钮,并且重新启动应用程序时,以前的数据不可用(是因为我点击了xcode上的停止)
    • managedObjectContext不是nil
    • NSManagedObjectContext方法save:返回YES

    插入对象的代码

    Test *test = [NSEntityDescription insertNewObjectForEntityForName:@"Test" inManagedObjectContext:self.database.managedObjectContext];
    

    要保存的代码:

    //database is a property of the type UIManagedDocument
    
    NSSet *setBeforeSave = [self.database.managedObjectContext insertedObjects];
    NSLog(@"setBeforeSave.count = %i", setBeforeSave.count);
    
    NSError *error = nil;
    
    if(![self.database.managedObjectContext save:&error])
        NSLog(@"error = %@", error);    
    
    NSSet *setAfterSave = [self.database.managedObjectContext insertedObjects];
    NSLog(@"setAfterSave.count = %i", setAfterSave.count);
    

1 个答案:

答案 0 :(得分:5)

根据UIManagedDocument文档,您不应该在任何一个内部托管上下文中调用save。相反,如果你想保存数据,你应该做两件事之一。

  1. 使用undoManager,因为它会将上下文标记为脏,并准备保存。

  2. 调用[document updateChangeCount:UIDocumentChangeDone];

  3. 因此,在您的情况下,您应该用以下方式替换该保存呼叫:

    [self.database updateChangeCount:UIDocumentChangeDone];
    

    您的数据将被保存。

    修改

    提供更多细节。 UIManagedDocument在父/子关系中有两个MOC。子项是调用document.managedObjectContext时获得的子项。现在,当NSManagedObjectContext具有父级时,将更改传播到父级的常规方法是调用save:。但是,UIManagedDocuememt执行其他操作,其文档明确指出不要在父或子上下文中调用save。

    那么,如何保存东西呢?好吧,你告诉UIManagedDocument它是“脏”的并且需要保存。您可以通过使用undoManager或调用updateChangeCount来实现这两种方式:。

    在执行其中任何一项操作时,UIManagedDocument的内部将确保向父上下文通知更改。在将来的某个时刻,父级将对实际的后备存储(即磁盘上的文件)进行更改。

    此外,当上下文被“保存”时,它可能会或可能不会保留对已更改的对象的引用。您可以设置一个属性,告诉它保留已保存的对象,或者释放它们。

    希望这可以解决您的问题。

    总结一下,看看原来的答案。

    顺便说一下,你可以通过在命令行参数中添加“-com.apple.CoreData.SQLDebug 1”来实际查看SQL存储正在做什么的日志。您可以在“编辑方案”对话框中执行此操作。