在彼此之后过早调用UITableView的reloadData时崩溃

时间:2013-04-04 12:56:34

标签: objective-c cocoa-touch uitableview

我有一个文本字段,在用户键入名称时显示建议的表格视图。数据源的过滤是在后台线程中进行的,因为它可能需要一些时间。

- (IBAction)personNameChanged:(UITextField *)sender
{
    NSString *name = sender.text;

    [backgroundThread performBlock:^{
            [self.personsDataSource filterDataSourceByName:name];
            [mainThread performBlock:^{
                [self.autoCompleteTableView reloadData];
            }];
    }];
}

[UITableView reloadData]来电:

  • -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

...同时所有细胞同步:

  • - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

...稍后会被调用。

问题是当用户快速键入时,可能会在所有单元格加载之前调用filterDataSourceByName。然后为不存在的indexPath调用cellForRowAtIndexPath

在调用reloadData时,如何解决此问题,以至于没有加载上次重新加载的所有单元格?

1 个答案:

答案 0 :(得分:8)

表视图的新数据源数组的分配也必须在主线程上完成,例如:

- (IBAction)personNameChanged:(UITextField *)sender
{
    NSString *name = sender.text;
    [backgroundThread performBlock:^{
            // Store filtered array into separate array here:
            NSArray *filteredPersons = [self.personsDataSource filterDataSourceByName:name];
            [mainThread performBlock:^{
                // Assign to table view data source array here:
                self.dataSourceArray = filteredPersons;
                [self.autoCompleteTableView reloadData];
            }];
    }];
}

否则可能会发生数据源数组在后台线程上被修改,同时被主线程上的表视图访问。