如何在不通知 NSFetchedResultsController 的情况下更新 NSManagedObject 或 NSManagedObjectContext
Posted
技术标签:
【中文标题】如何在不通知 NSFetchedResultsController 的情况下更新 NSManagedObject 或 NSManagedObjectContext【英文标题】:How to update a NSManagedObject or NSManagedObjectContext without notifying a NSFetchedResultsController 【发布时间】:2013-12-27 14:25:41 【问题描述】:我有一个托管对象上下文,其中有几个 NSFetchedResultsController
s 在整个应用程序中监听不同的实体,大部分情况下都可以正常工作。
我不知道如何解决以下情况:当用户单击实体的相应表格视图单元格中的按钮时,我正在设置实体上的关系。这当前会导致实体发生变化,FRC 会告诉 tableview 重绘整个单元格,将按钮呈现在其默认的控制状态。
有没有办法在不被我的 FRC 注意到的情况下更改实体?
与暂时禁用整个 FRC 相比,我希望能够仅对特定更新(由我自己控制,例如设置或删除关系)产生这种影响,以免失去其他更新的功能这可能同时发生。
谢谢!
【问题讨论】:
我正在考虑使用布尔值来实现您的目标。该值将允许您控制NSFetchedResultsController
委托将如何响应更新..
问题是单元格被“立即”重绘,取消了 UI 的正常过渡动画,对吗?
【参考方案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:看来我评论中的假设是错误的,所以我删除了它。以上是关于如何在不通知 NSFetchedResultsController 的情况下更新 NSManagedObject 或 NSManagedObjectContext的主要内容,如果未能解决你的问题,请参考以下文章
收到 FCM 通知时如何在不点击通知的情况下打开(启动)应用程序
如何在不显示通知的情况下 startForeground()?
在 Android 11 上,如何在不实际点击通知的情况下从通知更新启动 Activity