2

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

- (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在所有单元格加载之前调用它。然后cellForRowAtIndexPath为不存在的 indexPath 调用。

当调用 reloadData 太快以至于没有加载上次重新加载的所有单元格时,你应该如何解决这个问题?

4

1 回答 1

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];
            }];
    }];
}

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

于 2013-04-04T13:11:56.460 回答