当我们tableview需要上拉加载更多数据后,返回顶部下拉刷新数据,这个时候需要对dataSource removeAllData,然后添加新的dataSource,对tableview relaodata,停止mjrefresh,可能会导致crash.主要原因是将dataSource操作放在了子线程中,而当我们停止mjrefresh时候,会导致屏幕外的cell进入屏幕,触发tableView:tableView cellForRowAtIndexPath:方法.由于以前的dataSource已经被清除,假如此时新dataSource的索引小于indexPath.row就会导致数组越界.(注意此时,reloaddata方法还没执行).
该如何解决啦?
- 将
reloaddata和dataSource的操作放在mainThread中执行(建议这么做)
dispatch_async(dispatch_get_main_queue(), ^{
dataSource remove or add...
[selfWeak.tableView reloadData];
});
或者
@autoreleasepool{
dataSource remove or add...
[self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
}
- 我因为业务代码封装的原因,将停止
mjrefresh的操作和reloadData放在mainThread中,主要原因是我的dataSouce是在子线程中进行的.
- (void)endMJRefreshIfHasNextPage:(BOOL)hasNextPage{
@weakObj(self);
dispatch_async(dispatch_get_main_queue(), ^{
if (hasNextPage == NO) {
selfWeak.tableView.mj_footer.state = MJRefreshStateNoMoreData;
}
if(selfWeak.tableView.mj_header.isRefreshing){
[selfWeak.tableView.mj_header endRefreshing];
}else if (selfWeak.tableView.mj_footer.isRefreshing){
if (hasNextPage == NO) {
[selfWeak.tableView.mj_footer endRefreshingWithNoMoreData];
}else{
[selfWeak.tableView.mj_footer endRefreshing];
}
}
});
}
- (void)reloadData{
@weakObj(self);
dispatch_async(dispatch_get_main_queue(), ^{
[selfWeak.tableView reloadData];
});
}
这里我要吐槽一下后台,请求第一次只给了两条可用数据,其他都是没筛选的垃圾数据.然后下一页都是可用数据,当我再次回到顶部下拉刷新就出现了上面的问题.

11月-09-2018 15-23-30.gif