在更新NSFetchedResultsControllers之前,Core Data是否实际保存了对磁盘的任何更改?

这是一个非常具体的问题,我刚才被它咬了,所以为了节省他人一些时间和痛苦,这是我的问题深入和解决方案。

例如,当您保存主上下文并触发NSFetchedResultsController委托回调时,您是否可以依赖保存实际已完成的事实,并且可以安全地在这些回调中执行新的获取请求,假设将包含当前保存的数据?

答案是不。

如果你的应用程序中有一个活动的NSFetchedResultsController(NSFRC),它有一个委托集并且正在监视对相关对象的更改,那么这是一个小的未记录的警告,所有Core Data开发人员都应该注意这一点。 如果你对主上下文执行保存,并让NSFRC在主上下文上工作,那么在主上下文中调用save:实际上会首先更新NSFRC并调用willChangeContent:..didChangeContent:..等等回调willChangeContent:..在将MOC内容实际保存到磁盘之前,您的NSFRC委托。

这可能有问题的原因是如果您尝试在这些NSFRC回调中使用NSDictionaryResultType的resultType执行新的获取请求,那么您的获取请求将不包括任何当前更改。 根据当前的变化,我指的是首先调用NSFRC回调的那些变化。

您不会看到这些更改的原因是因为将resultType设置为NSDictionaryResultType会关闭includesPendingChanges属性。 因此,获取请求仅直接从磁盘获取更改,并且不会合并来自上下文的任何本地更改。

我可以理解为什么使用字典结果类型的任意提取请求不会将未保存的结果与上下文合并的原因,因为字典可以具有任意结构,而MOC是在图形中建模对象和关系,但是,部分是很有趣,令我惊讶的是NSFRC代表在实际执行保存之前获得了更新回调。

这是一些ASCII艺术:

     1.保存主要MOC  - > |  2. NSFRC回调 - > |  3.实际保存发生在这里
                          |  |  |            
                          |  |  |
                          |  ▼|
                          |  NSDictionaryResultType |
                          | 获取请求不会|
                          | 看到来自|的任何变化
                          | 这个当前的保存,但是
                          | 常规获取请求|
                          | 会看到那些变化|

PS:Core Data是一个在有限性能设备上运行的对象图管理框架。 有时你需要优化。