如何刷新 UITableViewController 或 NSFetchedResultsController?
Posted
技术标签:
【中文标题】如何刷新 UITableViewController 或 NSFetchedResultsController?【英文标题】:How to refresh a UITableViewController or NSFetchedResultsController? 【发布时间】:2010-06-19 21:38:13 【问题描述】:我的 UITableViewController 或 NSFetchedResultsController 有一点问题。我不确定哪个是问题,但我猜它是 UITableViewController。
正如我所说,我使用 NSFetchedResultsController 将数据填充到 UITableViewController 中。数据按日期排序,也按日期-年份显示在部分中,例如2010 年 5 月/2010 年 6 月/等等。这显示为节标题。
现在,当我添加新数据时,它会自动使用当前日期作为默认日期,但如果我想使用日期,则当前不在部分列表中,例如2010 年 4 月(当前为 5 月和 6 月在列表中),则显示不正确。只有当我退出应用程序并重新启动它时,它才会显示新的部分标题,一切都很好。
所以我不知何故需要能够刷新我的列表或更新它。只是将其添加到上下文中并对其进行更改似乎不会更新它。
再次,我不确定我需要更新什么,是我的 NSFetchedResultsController 对象还是 UITableViewController。
更新 #1:
我刚刚发现这个方法有一个异常:
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
// The fetch controller has sent all current change notifications, so tell the table view to process all updates.
[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:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
// [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
// Reloading the section inserts a new row and ensures that titles are updated appropriately.
[tableView reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade];
break;
此方法几乎取自 Apple 的 CoreDataBooks 示例。这是错误:
严重的应用程序错误。一个 从委托中捕获了异常 NSFetchedResultsController 在一个 调用 -controllerDidChangeContent:。 *** -[NSMutableArray removeObjectAtIndex:]: 超出索引 1 使用 userInfo (null) 限制 [0 .. 0]
之后,编辑模式(删除按钮出现的地方)不再起作用。
谢谢。
【问题讨论】:
【参考方案1】:好的,看来我找到了解决方案,我只是跳过这些
[self.tableView beginUpdates];
[self.tableView endUpdates];
并且总是这样做。
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
[self.tableView reloadData];
我显然会给出更多的逻辑,因为只有当我想将我的数据移动到以前不存在的部分中时才会出现问题。在有人能给我一个真正的解决方案之前,我会选择这个。
【讨论】:
我在 WWDC 与一位 Apple 工程师讨论过这个问题。他说这是 UITableView 中的一个错误(已在 4.0 中修复)。如果您使用的是 reloadData。如果您使用 >= 4.0,请按照文档中的说明进行操作。 您,先生,刚刚解决了一个问题,该问题在第 6 个小时内就已经流血了。如果我可以投票两次,我会的。【参考方案2】:在1.2版本的iPhoneCoreDataRecipes中采用Apple的修复,正确的做法是替换
// Reloading the section inserts a new row and ensures that titles are updated appropriately.
[tableView reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade];
与
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
(FileMerge 是你的朋友!)
请注意,1.2 版中还有另一个修复程序可以防止在创建新条目时出现异常崩溃。我已经报告了这个问题,它在两周内得到了修复。我鼓励您向 Apple 提交错误报告。它们的响应速度比您想象的要快得多,您可以期望得到最好的解决方案。
【讨论】:
【参考方案3】:您需要实现controller:didChangeSection:atIndex:forChangeType:
委托方法。在其中,根据报告的更改类型,将insertSections:withRowAnimation:
、deleteSections:withRowAnimation:
和reloadSections:withRowAnimation:
消息发送到您的表格视图。
【讨论】:
这就是我在问题中添加的内容...,之后出现异常。 你甚至没有提到controller:didChangeSection:atIndex:forChangeType:
。
isnt -controller:didChangeObject:atIndexPath: forChangeType:newIndexPath 做同样的事情吗?
好吧,正如文档所说,一个通知您对象的更改,另一个通知您部分的更改。由于您显然在更改部分时遇到问题,因此问题可能出在我提到的方法上。
对不起,我实际上已经实现了那个方法。我基本上是从 CoreDataBooks 示例中复制而来的。以上是关于如何刷新 UITableViewController 或 NSFetchedResultsController?的主要内容,如果未能解决你的问题,请参考以下文章