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

the*_*jaz 2 cocoa-touch objective-c uitableview

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

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

    [backgroundThread performBlock:^{
            [self.personsDataSource filterDataSourceByName:name];
            [mainThread performBlock:^{
                [self.autoCompleteTableView reloadData];
            }];
    }];
}
Run Code Online (Sandbox Code Playgroud)

[UITableView reloadData] 要求:

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

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

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

......稍后会被召唤.

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

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

Mar*_*n R 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];
            }];
    }];
}
Run Code Online (Sandbox Code Playgroud)

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