您的位置:首页 > Web前端

NSFetchedResultsController bug:have no insertion

2014-06-25 20:53 246 查看
这也许是NSFetchedResultsController的一个bug,maybe....

出错场景:

1、当我在输入框输入一长段文字,点击发送按钮,随即将消息保存至数据库。

2、数据库的变化激活NSFetchedResultsController,随即回调一系列的方法来更新tableview

3、问题是,我insert一条数据到数据库,但是NSFetchedResultsController的回调中没有insertion,只有update

4、导致tableview endupdates时报错 uitableview _endcellanimationswithcontext

分析:

1、输入信息多了才会出现这个bug

2、数据库保存成功,信息成功存到了sqlite文件

3、再次进入tableview可以正常显示刚才没有显示的那一条信息

解决方案:

输入信息的长度我们不能限制,所以NSFetchedResultsController不给我们回调insertion是无法避免了

所以在出现上述bug后,采用reloaddata来弥补。

具体做法:

判断是否出现了上述bug

<span style="font-size:14px;">        case NSFetchedResultsChangeUpdate:{
NSInteger row = [_conversationTableView numberOfRowsInSection:0];
if(row <= indexPath.row) {
//没有NSFetchedResultsChangeInsert返回
//tableview的row 和 数据库中数据的row 不一致
//因为tableview 没有 insert,所以row <= indexPath.row 就是出现bug

//弥补措施
[tableview reloadData];
}
<span style="white-space: pre;">	</span>}</span>


注意,beginUpdates 和 beginUpdates
的使用
reloadData不要放在beginUpdates 和 beginUpdates之间

我的代码:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller is about to start sending change notifications, so prepare the table view for updates.
DDLogInfo(@"ConversationController ---- willchange row of table :%ld",(long)[self tableView:_conversationTableView numberOfRowsInSection:0]);
}

- (void)controller:(NSFetchedResultsController *)controller
didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath
forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
switch(type) {
case NSFetchedResultsChangeInsert:
[_conversationTableView beginUpdates];
[_conversationTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
[_conversationTableView endUpdates];

break;

case NSFetchedResultsChangeDelete:
[_conversationTableView beginUpdates];
[_conversationTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[_conversationTableView endUpdates];

break;

case NSFetchedResultsChangeUpdate:{

NSInteger row = [_conversationTableView numberOfRowsInSection:0];
if(row <= indexPath.row){
[_conversationTableView reloadData];
//发送文字过长,fetchresultcontroller没有对tableview insert,所以在此处通过row的对比判断是否发生了上述bug
break;
}
[_conversationTableView beginUpdates];
[_conversationTableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[_conversationTableView endUpdates];

break;
}

case NSFetchedResultsChangeMove:
[_conversationTableView beginUpdates];
[_conversationTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[_conversationTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
[_conversationTableView endUpdates];

break;
}
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller has sent all current change notifications, so tell the table view to process all updates.

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: