代码之家  ›  专栏  ›  技术社区  ›  RunLoop

使用nsfetchedresultsController处理背景更改

  •  3
  • RunLoop  · 技术社区  · 14 年前

    我有一些关于未保存的结果控制器和coredata的问题,任何一个问题我都会非常感谢得到帮助。

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

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

    问题3-删除节:当删除一行导致删除节时,我得到“节中的行数无效?”??”错误。我通过从nsfetchedresultschangemove:节中删除“reloadsection”行并将其替换为“[tableview insertrowsatindexpaths…”,来解决这一问题,但再一次,我不确定这是否是最佳解决方案。

    任何帮助都将不胜感激。谢谢您!

    2 回复  |  直到 10 年前
        1
  •  11
  •   TechZen    14 年前

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

    问题1是由于FRC使用缓存对象(其ID未更改)而导致的,当您添加或删除更改ID并强制更新缓存但更改对象属性并不可靠的对象时。

    问题2是由FRC检查缓存中的对象引起的。最有可能的是,对象有一个持久存在于缓存中的不受影响的关系。当您在后台删除它时,FRC试图在关系的另一端的对象中出错,而不能。

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

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

    1. (首选)不要使用缓存。创建frc时,将cache属性设置为nil。
    2. 只要后台进程更改了数据模型,就清除缓存。

    当然,两种方法首先会破坏使用缓存的目的。

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

        2
  •  0
  •   Stephan    12 年前

    我的建议是:

    • 检测后台线程上所需的更改
    • 将更改作为有效负载发布到主线程
    • 进行实际更改并保存在主线程上(主线程上的托管对象上下文)
    • 一定要使用frc的缓存,这样性能会更好。
    • 引自迈克尔·普里瓦特、罗伯特·华纳的《iOS专业核心数据》:

      核心数据智能地管理其缓存,这样,如果结果被另一个调用更新,缓存会在受到影响时被删除。