当 didChangeObject 被调用 NSFetchedResultsController 时,UITableView 没有更新
Posted
技术标签:
【中文标题】当 didChangeObject 被调用 NSFetchedResultsController 时,UITableView 没有更新【英文标题】:UITableView isn't updating when didChangeObject is called NSFetchedResultsController 【发布时间】:2013-10-10 21:31:01 【问题描述】:我在 UITableView 中使用 NSFetchedResultsController。我成功地收到了对- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
的委托调用,但是我对 UITableView 中的插入/更新/删除行所做的任何更改都没有真正显示出来。我什至只是尝试在 UITableView 上设置背景颜色以查看是否会显示任何更改,但除非我推送新的视图控制器然后弹回,否则它们不会显示。然后我会看到背景颜色和表格更新。
我对 didChangeObject: 方法的实现实际上只是样板模板:
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
[self.tableView beginUpdates];
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
[self.tableView endUpdates];
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
UITableView *tableView = self.tableView;
switch(type)
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
tableView.backgroundColor = [UIColor redColor];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
tableView.backgroundColor = [UIColor blueColor];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
我在导航栏中添加了一个带有 IBAction 的按钮,它只调用 [self.tableView reloadData];
,每当我点击它时,所有的插入和更新都会显示在表格中。但是,它们不会在更改发生时显示出来。
怎么了?
【问题讨论】:
你能确认cellForRowAtIndexPath
没有被调用吗?
cellForRowAtIndexPath
在更新期间被调用,但这些更新实际上并未显示在 UI 中。在插入过程中,cellForRowAtIndexPath
也会被调用,但这些行永远不会出现在 UI 中。
奇怪,你的cellForRowAtIndexPath
长什么样子?
发现问题,查看下方答案。
【参考方案1】:
看起来对 didChangeObject
(和其他方法)的委托调用并未在主线程上发生,这意味着它们无法更新 UI,但这些更改只是默默地被删除了。
我更新了上面包含的三个方法,以便这些方法的主体都在主线程上分派,并且一切都按预期工作。下面是一个例子:
dispatch_sync(dispatch_get_main_queue(), ^
[self.tableView beginUpdates];
);
【讨论】:
您不必在单独的线程中执行此操作,请检查 raywenderlich 实现:raywenderlich.com/999/… 这里可能存在更大的问题,您应该确保对上下文的更改也发生在主线程上。 你有没有发现为什么这些委托调用发生在后台线程上?我在后台有一个子上下文,当它保存时,它会导致这些调用在后台发生。我希望子上下文在保存时将更改推送到主上下文。 FRC 正在使用主要上下文,所以我找不到问题。以上是关于当 didChangeObject 被调用 NSFetchedResultsController 时,UITableView 没有更新的主要内容,如果未能解决你的问题,请参考以下文章
NSFetchedResultsController 没有调用 didChangeObject
NSFetchedResultsController 并不总是为 NSFetchedResultsChangeMove 调用 didChangeObject:atIndexPath:forChange
Swift 2.0 转换问题 NSFetchedResultsController didChangeObject
NSFetchedResultsController didChangeObject indexPath 为空
带有过滤 NSPredicate 的 NSFetchedResultsController didChangeObject
带有 didChangeObject 的 NSFetchedResultsController 在表格视图中显示单元格的速度很慢