[UITableView _contentOffsetForScrollingToRowAtIndexPath:atScrollPosition:]:row (x) beyond bounds...

今天开发 崩溃 报错:
[UITableView _contentOffsetForScrollingToRowAtIndexPath:atScrollPosition:]:row (x) beyond bounds...

原因:
执行
[UITableView reloadDate]
或者其他刷新 UITableView 的方法;
Cell 计算量 数据量比较大的情况下,在一个run loop周期没执行完;
UITableView 会可能在数据还没加载完就立即去执行
数据源-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section方法。
可能会有崩溃情况。

解决方法:

逻辑:把数据加载放回主线程,先保证数据加载完整了再执行数据源的代理方法。

方法一:
等待线程完成

//1.先让 reloadDate 在主队列执行
[tableView reloadData];

//2.dispatch_get_main_queue会等待机会,直到主队列空闲,也就是数据加载完毕才继续执行。
dispatch_async(dispatch_get_main_queue(), ^{
//刷新完成 / 各种操作
//我之前崩溃就是这个刷新 会有崩溃 置入 这里就没有崩溃情况
[tableView reloadSections:[[NSIndexSet alloc] initWithIndex:section] withRowAnimation:UITableViewRowAnimationAutomatic];
});

方法二:
进行重绘

[tableView reloadData];

// 强制重绘并等待完成
[tableView layoutIfNeeded];

//我之前崩溃就是这个刷新 会有崩溃 置入 这里就没有崩溃情况
[tableView reloadSections:[[NSIndexSet alloc] initWithIndex:section] withRowAnimation:UITableViewRowAnimationAutomatic];

推荐!(新增)方法三:

逻辑:判断 UITableView 是否加载完成(是否存在), 完成后再继续下一步

-(void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath )indexPath
{
//用于判断tableview当前是否加载完成
if([indexPath row] == ((NSIndexPath
)[[_mainTableView indexPathsForVisibleRows] lastObject]).row){

    //加载已结束 表示已存在
    
    dispatch_async(dispatch_get_main_queue(),^{
        
        //dispatch_get_main_queue会等待机会,直到主队列空闲,也就是数据加载完毕才继续执行。
        [tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
        /*
         刷新 、定位 等操作  可以置入这里。
         也可以提取方法到外面去,会灵活点。
         这个主要是判断存在与否  [indexPath row] == ((NSIndexPath*)[[tableView indexPathsForVisibleRows] lastObject]).row
         */
        
    });
    
}

}

以上三个方法,个人推荐第三个方法。

你可能感兴趣的:([UITableView _contentOffsetForScrollingToRowAtIndexPath:atScrollPosition:]:row (x) beyond bounds...)