我有一个文本字段,在用户键入名称时显示建议的表格视图。数据源的过滤是在后台线程中进行的,因为它可能需要一些时间。
- (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时,如何解决此问题,以至于没有加载上次重新加载的所有单元格?
答案 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];
}];
}];
}
否则可能会发生数据源数组在后台线程上被修改,同时被主线程上的表视图访问。