有两个实体 - 文档和页面。文档与Page有一对多的关系。
添加文档时保存托管对象上下文。此时,它们中没有页面。在调试时我发现编写器上下文的save方法确实被调用并且执行时没有错误。我关闭并重新打开应用程序,我找不到以前保存的Document对象。但是,如果我在其中一个文档中添加了一个页面,那么Document对象就会出现在表格中。我使用工具查看SQLite文件,但我的观察不是基于我在工具中看到的。即使我调试并查看存在的文档数量,当没有页面时我也会返回0。
我猜测持久存储协调器正在进行某种优化以批量编写。我可以强制它立即写入和更新持久性存储吗?在持久性存储对象上调用addPersistentStoreWithType
时是否可以添加一个选项?
注意:仅供参考,我使用this模式来组织托管对象上下文
修正了问题。这是更新 所以,我一直在保存整个堆栈直到编写器上下文。这个bug非常愚蠢。我试图在主线程上保存主要上下文,如下所示:
- (void)saveMainContext {
[self.mainManagedObjectContext performBlock:^{
// Ensure that the main object context is being saved on the main queue
__block NSError *error = nil;
dispatch_async(dispatch_get_main_queue(), ^{
[self.mainManagedObjectContext save:&error];
});
if(!error)
{
//Write to disk after saving on the main UI context
[self saveWriterContext];
}
}];
}
如您所见,在尝试保存主上下文后,我保存了编写器上下文。但是,错误是我没有等待主要上下文完成保存。修复bug后,我的代码如下所示:
- (void)saveMainContext {
[self.mainManagedObjectContext performBlock:^{
// Ensure that the main object context is being saved on the main queue
dispatch_async(dispatch_get_main_queue(), ^{
NSError *error = nil;
[self.mainManagedObjectContext save:&error];
if(!error)
{
//Write to disk after saving on the main UI context
[self saveWriterContext];
}
});
}];
}
而且,这解决了这个问题!我这是非常愚蠢的错误。
答案 0 :(得分:1)
您确定要保存整个堆栈吗?如果您在私有上下文中进行更改,则需要保存该私有上下文。如果在主上下文中(从UI)进行更改,则需要保存该上下文。只有在您将所有其他上下文报告NO
到-hasChanges
之后,才应保存编写器上下文(也就是设计中的主上下文)。
我怀疑这是你的问题。
嗯。不知道那个。谢谢!所以,如果我根本不检查“错误”,你是否建议我可能会好起来,只是检查保存的回报?
我所说的是你的保存应该是这样的(注意我也纠正你不必要的dispatch_async):
- (void)saveMainContext {
[self.mainManagedObjectContext performBlock:^{
// Ensure that the main object context is being saved on the main queue
NSError *error = nil;
if (![[self mainManagedObjectContext] save:&error]) {
NSLog("Failed to save context: %@\n%@", [error localizedDescription], [error userInfo]);
exit(1);
}
[self saveWriterContext];
}];
}
dispatch_async
将被忽略,因为您已经在正确的队列中。
对-save:
的调用会返回bool
。如果和仅,如果返回NO
,您是否对error
做出了反应。