NSManagedObjectContext refreshObject导致NSFetchedResultsController中的重复项

时间:2016-04-23 06:35:22

标签: ios objective-c core-data

我有一个问题,如果我更改核心数据对象,保存然后刷新对象,导致我的NSFetchedResultsController显示重复的对象。我想我明白发生了什么,但我正在找人确认,也希望能提供一些更详细的信息。

为了更详细地解释,我有两个实体,FixturePositionFixture有多个Positions,而Position只属于一个Fixture。要重现此问题,请执行以下操作:

  1. 获取所有职位。
  2. 修改该对象Fixture上的某个值(任何一个)。 I.E foo.fixture.name = "foobar"
  3. 保存上下文
  4. 通过调用context.refreshAllObjectscontext.refreshObject(foo, mergeChanges: false/true)来刷新对象。
  5. 我有一个使用获取结果控制器的tableview,它显示了Fixures。执行上述操作后,tableview将显示每个项目的重复项(如果我使用FRC的委托方法进行更新,或者我只是重新加载tableview,则无关紧要)。

    看起来正在发生的事情是刷新使FRC知道的对象无效,同时获得另一组对象的知识。如果,在第5步,我拨打frc.performFetch(),那么问题就会消失。

    其他注意事项:

    • 无论我运行多少次代码,我只得到每个对象的两个(我使用一个随机按钮来触发它进行测试)。
    • 一旦我在下一次代码运行期间访问我的对象的Fixture属性(即调用刷新后),就会在我的Fixture子类上调用
    • init(entityName,context)。
    • 在我的示例中,所有内容都发生在相同的上下文中(尽管它也发生在子上下文中)

    为了让我了解自己如何在这种情况下获得更多的背景信息,用户可以点击列表中的固定装置然后最终在几个屏幕上缩小一个位置,以便他们可以执行修改的操作夹具。此时应用程序的其他活动区域正在侦听NSManagedObjectContextDidSaveNotification,我希望它们更新它们的对象以便它们显示正确的数据,这就是我调用refresh的原因。

    我在文档中进行了挖掘,我看不到任何具体解释我的理论的内容,即更新上下文会导致NSFetchedResultsController具有无效对象。任何人都可以对这种行为有所了解吗?

1 个答案:

答案 0 :(得分:0)

首先,您真的不应该覆盖-init...上的NSManagedObject。这是你强烈反对覆盖的方法之一,很容易成为你问题的根源。

其次,您的整个UI应该使用与主队列关联的NSManagedObjectContext的单个实例,因此您的UI中应该只有 ONE 实例。 。如果你有多个上下文,那么你自己就会让事情变得更复杂。如果您正在使用单个上下文,请记住,无论您针对该上下文获取对象多少次,您都将获得完全相同的指针。

NSFetchedResultsController永远不会创建对象,它只会提取并提供它们以供显示。因此,NSFetchedResultsController仅报告您在代码中的其他位置创建了此重复项的事实。

现在有些问题,这些重复内容会被推送到磁盘吗?

你能在磁盘上的商店文件中看到它们吗?

当您重新启动应用程序时,仍然存在重复项吗?

当您在-init上的自定义NSManagedObject方法中打印时;他们不止一次开火吗?