核心数据:SQLite 没有立即更新
Posted
技术标签:
【中文标题】核心数据:SQLite 没有立即更新【英文标题】:Core Data: SQLite not being updated immediately 【发布时间】:2016-03-31 13:48:37 【问题描述】:有两个实体——文档和页面。 Document 与 Page 是一对多的关系。
我在添加文档时保存了托管对象上下文。此时,其中没有页面。在调试时,我发现编写器上下文的保存方法确实被调用并且没有错误地执行。我关闭并重新打开应用程序,但找不到以前保存的 Document 对象。但是,如果我在其中一个文档中添加一个页面,那么 Document 对象就会出现在表格中。我使用工具查看 SQLite 文件,但我的观察不是基于我在工具中看到的。即使我调试并查看存在的文档数量,当其中没有页面时,我也会返回 0。
我猜 Persistent Store Coordinator 正在做某种优化以批量写入。我可以强制它立即写入和更新持久存储吗?在持久存储对象上调用addPersistentStoreWithType
时,我可以添加一个选项吗?
注意:仅供参考,我使用this 模式来组织托管对象上下文
解决了这个问题。这是更新 因此,我将整个堆栈一直保存到 writer 上下文。这个错误非常愚蠢。我试图像这样在主线程上保存主上下文:
- (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];
];
如您所见,在尝试保存主要上下文之后,我保存了编写器上下文。但是,错误是我没有等待主要上下文完成保存。修复错误后,我的代码如下所示:
- (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];
);
];
而且,这解决了问题!我犯了一个非常愚蠢的错误。
【问题讨论】:
【参考方案1】:您确定要保存整个堆栈吗?如果您在私有上下文中进行更改,则需要保存该私有上下文。如果您在主上下文中进行更改(从 UI),那么您需要保存该上下文。只有在所有其他上下文报告 NO
到 -hasChanges
之后,您才应该保存作者上下文(也就是他设计中的主上下文)。
我怀疑这是你的问题。
对 OP 的回应
嗯。不知道。谢谢!那么,如果我根本不检查“错误”而只检查保存的返回,您是否建议我可能会过得很好?
我的意思是你的存档应该是这样的(注意我还纠正了你不必要的 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
做出反应。
【讨论】:
谢谢马库斯!我浏览了整个堆栈,并确保按照您的建议按顺序保存上下文,并找到了错误。非常感谢!是的,我应该将 hasChanges 添加到我的保存方法中。 并且保存后不要检查错误。您关注的作者不正确。检查来自-save:
的返回并回复。即使没有发生错误,也可以填充错误。
嗯。不知道。谢谢!那么,如果我根本不检查“错误”而只检查保存的返回,您是否建议我可能会过得很好?
更新答案以澄清我的 cmets 关于error
。以上是关于核心数据:SQLite 没有立即更新的主要内容,如果未能解决你的问题,请参考以下文章
更改核心数据堆栈后使用核心数据创建 SQLite 文件后未更新