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

use*_*037 1 core-data nsmanagedobjectcontext ios

概观

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

  1. 保存真的发生了吗?
  2. 我是否面临问题,因为我创建了一个基于视图的应用程序(核心数据复选框不可用)?

接下来的步骤

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

输出注意到了

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

插入对象的代码

Test *test = [NSEntityDescription insertNewObjectForEntityForName:@"Test" inManagedObjectContext:self.database.managedObjectContext];
Run Code Online (Sandbox Code Playgroud)

保存代码:

//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);
Run Code Online (Sandbox Code Playgroud)

Jod*_*ins 5

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

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

  2. 调用[document updateChangeCount:UIDocumentChangeDone];

因此,在您的情况下,您应该用以下方法替换该保存调用:

[self.database updateChangeCount:UIDocumentChangeDone];
Run Code Online (Sandbox Code Playgroud)

您的数据将被保存.

编辑

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

那么,如何保存东西呢?好吧,你告诉UIManagedDocument它是"脏"的并且需要保存.您可以通过使用undoManager或调用updateChangeCount来执行此操作的两种方法:

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

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

希望,这可以解决您的问题.

总而言之,请看原始答案.

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