场景:加载更多的表视图,滑动时根据偏移量动态加载更多数据《分页》同时存在数据源修改的操作《删除,修改》
日志:
#1453570 NSInternalInconsistencyException
Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (9) must be equal to the number of rows contained in that section before the update (10), 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).
UXLive -[ULUserGroupListViewController tableViewDeleteCellAtIndexPath:] (ULUserGroupListViewController.m:)
代码:
- (void)tableViewDeleteCellForGroupListInfoCell:(ULGroupListInfoCell *)groupListInfoCell{
//假设数据已经变更<加载更多>,此时获取到tempIndexPath仍然是我想要删除的。对数据源进行加锁,防止删除的过程中数据变化。UI删除完了以后进行数据源的同步
NSIndexPath *tempIndexPath = [self.tableView indexPathForCell:groupListInfoCell];
if (tempIndexPath != nil) {
[self.tableView beginUpdates];
@synchronized (self.viewModel.dataArray) {
[self.viewModel.dataArray removeObjectAtIndex:tempIndexPath.row];
[self.tableView deleteRowsAtIndexPaths:@[tempIndexPath] withRowAnimation:UITableViewRowAnimationLeft];
}
[self.tableView endUpdates];
}
//修改前
// [self.viewModel.dataArray removeObjectAtIndex:indexPath.row];
// [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
}
原理分析:同步操作
-主队列 删除操作
-全局队列 数据修改
1、传入具体的cell视图实体而非index索引。
2、通过cell视图反向查找index索引,进行判空操作。
3、对数据模型加锁,《先修改数据源,后进行实图更新》。
4、确保效率,锁外加入beginUpdates -endUpdates 加快效率。
方案分析:
1、可采用数组容器数据源的加锁操作,缺点容易引发业务人员乱用。当数据量大时候造成效率低下。
2、通过对表视图UI相关增加分类,使用时候通过规范确保正确使用《原因是只数据变化,并没有同时增删操作不会引发数组越界》
思考:如何不通过规范的手段来规避此类问题。