当我们tableview
需要上拉加载更多数据后,返回顶部下拉刷新数据,这个时候需要对dataSource removeAllData
,然后添加新的dataSource
,对tableview relaodata
,停止mjrefresh
,可能会导致crash
.主要原因是将dataSource
操作放在了子线程中,而当我们停止mjrefresh
时候,会导致屏幕外的cell
进入屏幕,触发tableView:tableView cellForRowAtIndexPath:
方法.由于以前的dataSource
已经被清除,假如此时新dataSourc
e的索引小于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
网友评论