相信很多人会遇到这种情况,当tableView正在滚动的时候,如果reloadData,偶尔发生App crash的情况。 这种情况有时候有,有时候没有,已经难倒了很多人。直至今天,我在stackoverflow上面,仍没有发现真正有说到其本质的帖子。我的处女贴,选择这个问题来阐述一下我的观点。
第一句话,阐述问题的本质:在tableView的dataSource被改变 和 tableView的reloadData被调用之间有个时间差,而正是在这个期间,tableView的delegate方法被调用,如果新的dataSource的count小于原来的dataSource count,crash就很有可能发生了。
下面的笔记提供了两种解决方案,和记录了一个典型的错误,即 在background thread中修改了datasource,虽然调用
[self.tableView performSelectorOnMainThread:
@selector(reloadData)
withObject:nilwaitUntilDone:NO];
记住正确的原则:
总是变化的DataSource和(注意这个和)reloaddata在主线程。更重要的是,reloaddata应该DataSource更改之后立即调用。
如果数据源改变但是TableView的reloaddata方法不立即调用,tableview可能会崩溃,如果它在滚动。
事故原因:有DataSource的变化和reloaddata之间的时间差距仍然是。如果表是滚动在时间上的差距,应用程序可能会崩溃的!!!!
错误的方式:
下面的代码是错误的:即使是在reloaddata主线程调用,有DataSource的变化和reloaddata之间的时间差距仍然是。如果表是滚动在时间上的差距,应用程序可能会崩溃的!!!!
错误代码样本:
-(void) changeDatasource_backgroundThread
{
@autoreleasepool{
[self.dataSourceArray removeAllObjects];
[self.tableView performSelectorOnMainThread:
@selector(reloadData)
withObject:nil waitUntilDone:NO];
}
}
正确的代码样本:
dispatch_async(dispatch_get_main_queue(), ^{
self.dataSourceArray= a new Array.
[self.tableView reloadData];
});