NSFetchedResultsController 与 UITableView 的问题
2014-06-25 20:09
330 查看
出错关键字:
出错场景:
聊天界面,点击输入文字,点击发送按钮(注:此问题为偶显,不容易重现导致此问题不易跟踪)
结果:程序没有crash,但是发送的消息没有展示在tableview上面,pop到联系人列表界面,再次进入消息界面,刚才发送的消息正常显示
我的用法:
分析:
1、重新进入聊天界面,消息正常展示,说明数据库中的数据是正确的
2、重新进入界面,会触发reloaddata方法,所以消息都展示出来了
3、确定所有tableview 的 insert 、delete、update、move都是在main thread,所以不是线程问题,而且线程问题不会报错
4、到底是什么原因呢
排错:
按住option键,单击 beginUpdates,查看description
理解一下:类似以下操作应该在beginUpdates和 endUpdates之间
review下自己的代码,发现确实有不少reloadRows操作没有在beginUpdates 和 endUpdates 之间,因为用了fetchresultcontroller,所以不用自己在其他地方做reload、insert、delete等操作,只需要修改数据库之后save就好了。接下来对tableview的操作都会在
----over----
An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent: Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (0), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). with userInfo (null)
出错场景:
聊天界面,点击输入文字,点击发送按钮(注:此问题为偶显,不容易重现导致此问题不易跟踪)
结果:程序没有crash,但是发送的消息没有展示在tableview上面,pop到联系人列表界面,再次进入消息界面,刚才发送的消息正常显示
我的用法:
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller { // The fetch controller is about to start sending change notifications, so prepare the table view for updates. [_conversationTableView beginUpdates]; }
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath { switch(type) { case NSFetchedResultsChangeInsert: [_conversationTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; break; case NSFetchedResultsChangeDelete: [_conversationTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop]; break; case NSFetchedResultsChangeUpdate:{ [_conversationTableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; break; } case NSFetchedResultsChangeMove: [_conversationTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; [_conversationTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; break; } }
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { // The fetch controller has sent all current change notifications, so tell the table view to process all updates. [_conversationTableView endUpdates]; }
分析:
1、重新进入聊天界面,消息正常展示,说明数据库中的数据是正确的
2、重新进入界面,会触发reloaddata方法,所以消息都展示出来了
3、确定所有tableview 的 insert 、delete、update、move都是在main thread,所以不是线程问题,而且线程问题不会报错
4、到底是什么原因呢
排错:
按住option键,单击 beginUpdates,查看description
Call this method if you want subsequent insertions, deletion, and selection operations (for example, cellForRowAtIndexPath: and indexPathsForVisibleRows) to be animated simultaneously. This group of methods must conclude with an invocation of endUpdates. These method pairs can be nested. If you do not make the insertion, deletion, and selection calls inside this block, table attributes such as row count might become invalid. You should not call reloadData within the group; if you call this method within the group, you will need to perform any animations yourself.
理解一下:类似以下操作应该在beginUpdates和 endUpdates之间
[_conversationTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
[_conversationTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
[_conversationTableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
review下自己的代码,发现确实有不少reloadRows操作没有在beginUpdates 和 endUpdates 之间,因为用了fetchresultcontroller,所以不用自己在其他地方做reload、insert、delete等操作,只需要修改数据库之后save就好了。接下来对tableview的操作都会在
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath;当中执行。
----over----
相关文章推荐
- NSFetchedResultsController和UITableView显示CoreData的数据时用relationship分组的方 ...
- iOS使用UIPageViewController结合多个UITableView后点击状态栏无法让UITableView置顶问题
- 在storyboard中的静态UITableView中拖入 UISearchBar and Search Display Controller出现的奇怪问题
- Implementing NSFetchedResultsController for UICollectionView
- Storyboard中 UIViewController+UITableView使用 autolayout引起的界面布局问题
- UISearchBar 和 UISearchDisplayController 没有在UITableView 的headerView 导致searchResultsTableView的frame出问题
- 在storyboard中的静态UITableView中拖入 UISearchBar and Search Display Controller出现的奇怪问题
- [ios开发基础之 Core Data[3]]如何使用NSFetchedResultsController 来集成TableView操作
- NSFetchedResultsController更新tableview出错
- iOS5中关于dismissModalViewController的问题
- [iOS]UINavigationController UITabBarController UITableView学习笔记
- 分组的UITableView在iPad上的背景问题
- UITableView在重绘时出现问题
- NSFetchedResultsController的使用
- 关于viewDidLoad里调用presentModalViewController的问题
- 关于navigationViewController与tabViewController组合使用的问题
- UITableView设置背景为透明时遇到的问题
- iphone ipad viewController不响应横竖屏转换相关消息的问题
- UINavigationController在viewWillAppear函数中pushViewController时的问题和解决
- Core Data 教程: 如何使用NSFetchedResultsController