UITableView reloadData的正确方法


相信很多人会遇到这种情况,当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];
});


你可能感兴趣的:(ios)