1

概述

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

问题

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

遵循的步骤

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

输出注意到

setBeforeSave.count = 1
setAfterSave.count = 0
  • 保存前,该NSManagedObjectContext方法insertedObjects返回 1 个对象
  • 保存前,NSManagedObjectContext方法insertedObjects返回0个对象
  • 当按下 Xcode 停止按钮时,当应用程序重新启动时,以前的数据不可用(是不是因为我在 xcode 上单击了停止)
  • managedObjectContext 不为零
  • 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);
4

1 回答 1

5

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

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

  2. 调用 [document updateChangeCount:UIDocumentChangeDone];

因此,在您的情况下,您应该将该保存调用替换为:

[self.database updateChangeCount:UIDocumentChangeDone];

您的数据将被保存。

编辑

提供额外的细节。UIManagedDocument 有两个 MOC。在父/子关系中。孩子是您在调用 document.managedObjectContext 时得到的那个。现在,当 NSManagedObjectContext 有父对象时,将更改传播到父对象的正常方法是调用 save:。但是,UIManagedDocuememt 做了其他事情,并且它的文档明确指出不要在父上下文或子上下文中调用 save。

那么,如何保存东西呢?好吧,您告诉 UIManagedDocument 它是“脏的”并且需要保存。有两种方法可以做到这一点,或者使用 undoManager,或者调用 updateChangeCount:。

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

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

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

不过,总结一下,请参阅原始答案。

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

于 2012-04-17T03:25:43.487 回答