使用NSFetchedResultsController处理后台更改

时间:2010-06-07 13:29:13

标签: iphone cocoa-touch cocoa core-data nsfetchedresultscontroller

我对NSFetchedResultsController和CoreData有一些唠叨的问题,其中任何一个我都非常感谢获得帮助。

问题1 - 更新:我在后台线程上更新我的商店,导致某些行被删除,插入或更新。使用“mergeChangesFromContextDidSaveNotification:”方法将更改合并到主线程的上下文中。插入和删除是正确更新的,但更新不是(例如,单元格标签未随更改而更新),尽管我已确认更新通过contextDidSaveNotifcation,与插入和删除完全相同。我目前的解决方法是暂时将上下文的过期间隔更改为0,但这似乎不是理想的解决方案。

问题2 - 删除对象:我的获取批量大小为20.如果对象被前20行中的后台线程删除,则一切正常。但是如果对象在前20行之后并且表向下滚动,则会引发“CoreData无法完成故障”错误。我已经尝试重新保存上下文并重新执行frc fetch - 一切都无济于事。注意:在这种情况下,不会为删除调用frc委托方法“didChangeObject ....” - 我认为这是因为当时有问题的对象没有出现故障(因为它超出了初始提取范围) )。但出于某种原因,上下文仍然认为对象已经存在,尽管已经从商店中删除了。

问题3 - 删除部分:当删除某行导致删除某个部分时,我得到了“部分中无效的行数???”错误。我通过从NSFetchedResultsChangeMove:部分删除“reloadSection”行并将其替换为“[tableView insertRowsAtIndexPaths ....”来解决这个问题。这似乎有效,但我再次确定这是否是最佳解决方案。

非常感谢任何帮助。谢谢!

2 个答案:

答案 0 :(得分:11)

我认为你所有的问题都与获取结果控制器的缓存有关。

问题1是由FRC使用缓存对象(其ID未更改)引起的。当您添加或删除更改ID并强制更新缓存但更改对象属性的对象时这样做可靠。

问题2是由FRC检查缓存中的对象引起的。最有可能的是,该对象具有在缓存中持久存在的默认关系。当您在后台删除它时,FRC会尝试在关系另一端的对象中出错,但不能。

问题3:同样的问题。缓存不反映更改。

当FRC以外的某个对象正在修改数据模型时,您真的不应该使用FRC的缓存。您有两种选择:

  1. (首选)不要使用缓存。创建FRC时,将cache属性设置为nil。
  2. 在后台进程改变数据模型的任何时候清除缓存。
  3. 当然,两个人首先失败了使用缓存的目的。

    缓存仅在数据基本上是静态和/或FRC管理更改时才有用。在任何其他情况下,您不应该使用它,因为FRC需要重复检查实际数据模型以确保它对数据有当前的理解。由于另一个输入可能已经改变了真实对象,所以它不能依赖于对象的复制。

答案 1 :(得分:0)

我的建议:

  • 检测后台线程所需的更改
  • 将更改作为有效内容发布到主线程
  • 进行实际更改并保存在主线程上(主线程上的托管对象上下文)
  • DO使用缓存作为FRC;你会得到更好的表现
  • 来自“Pro Core Data for iOS”的作者:Michael Privat,Robert Warner:

      

    “核心数据智能地管理其缓存,以便如果结果通过另一个调用更新,则缓存会在受影响时被删除。”