NSFetchedResultsController bug:have no insertion

这也许是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.

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值