【问题标题】:How to update a NSManagedObject or NSManagedObjectContext without notifying a NSFetchedResultsController如何在不通知 NSFetchedResultsController 的情况下更新 NSManagedObject 或 NSManagedObjectContext
【发布时间】:2013-12-27 14:25:41
【问题描述】:

我有一个托管对象上下文,其中有几个 NSFetchedResultsControllers 在整个应用程序中监听不同的实体,大部分情况下都可以正常工作。

我不知道如何解决以下情况:当用户单击实体的相应表格视图单元格中的按钮时,我正在设置实体上的关系。这当前会导致实体发生变化,FRC 会告诉 tableview 重绘整个单元格,将按钮呈现在其默认的控制状态。

有没有办法在不被我的 FRC 注意到的情况下更改实体?

与暂时禁用整个 FRC 相比,我希望能够仅对特定更新(由我自己控制,例如设置或删除关系)产生这种影响,以免失去其他更新的功能这可能同时发生。

谢谢!

【问题讨论】:

  • 我正在考虑使用布尔值来实现您的目标。该值将允许您控制NSFetchedResultsController 委托将如何响应更新..
  • 问题是单元格被“立即”重绘,取消了 UI 的正常过渡动画,对吗?

标签: ios cocoa-touch core-data nsfetchedresultscontroller


【解决方案1】:

可以使用“原始访问器”方法

[object setPrimitiveValue:... forKey:...]

因为这不会导致任何更改通知。但这可能有不想要的 副作用。

更好的解决方案可能是将按钮状态存储在(瞬态) 对象的属性,以便在单元格时可以正确恢复它 已重绘。

【讨论】:

  • 这是个好主意,但由于我在更新后立即保存上下文,所以无论如何我都会收到更改通知。有没有办法解决这个问题?
  • @akelagercrantz:我不知道。替代建议呢?
  • 它可以工作,但在我的场景中非常麻烦,因为按钮状态是临时的,并且会在一段时间后改变(点击后显示反馈 - 用户将产品添加到购物车)。
  • @akelagercrantz:但它可能发生在单元格被重绘的任何时候,由于滚动。
  • 确实,但我可以忍受。如果用户滚动并再次返回,按钮的反馈可能已经被注意到并且不再相关。
【解决方案2】:

也许我不明白您的问题,但如果您只想禁用 NSFetchedResultsController 委托并因此禁用渲染,正如我评论的那样,您可以为此使用 bool 值。

这里是基本的想法。在这里,stopAutomaticTrackingOfChanges 将是公共的,而 beganUpdates 可以在类扩展中维护。

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
    if (!self.stopAutomaticTrackingOfChanges) {
        [self.tableView beginUpdates];
        self.beganUpdates = YES;
    }
}

- (void)controller:(NSFetchedResultsController *)controller
  didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex
     forChangeType:(NSFetchedResultsChangeType)type
{
    if (!self.stopAutomaticTrackingOfChanges)
    {
        switch(type)
        {
            // your code here
        }
    }
}    

- (void)controller:(NSFetchedResultsController *)controller
   didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath
     forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath
{
    if (!self.stopAutomaticTrackingOfChanges)
    {
        switch(type)
        {
            // your code here
        }
    }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    if (self.beganUpdates) [self.tableView endUpdates];
}

这个想法取自斯坦福课程的CoreDataTableViewController.h/.m 代码(参考http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2011-fall)。

【讨论】:

  • @MartinR 我没有从问题中理解它。我将等待OP的详细信息。目前尚不清楚 OP 是否会这样做。感谢您的评论。无论如何,如果问题不正确,我将删除我的答案。谢谢。
  • @MartinR 在这种情况下,结果集的顺序不会改变。事实上,视图根本不会发生任何变化。这可能有效,但是我会错过同时发生的数据集的任何其他更改。这可能永远不会发生,但它可以。我宁愿在特定更改而不是特定时间段内禁用它。
  • @flexaddicted:看来我评论中的假设是错误的,所以我删除了它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-21
  • 2012-06-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多