我正在为iPhone创建一个词典应用程序,在用户输入时提供结果。我使用线程(NSThread)来更新UITableView,以便不阻塞主线程。
但是,当UITableView向数据源询问行数时会发生崩溃(tableView:numberOfRowsInSection :),然后我返回10,然后它会向数据源询问单元格0-9(tableView:cellForRowAtIndexPath: )。但是当它要求单元格7时,数据源已经改变了,现在它只有5行,从而导致崩溃。
以下是我解决问题的方法:
我在init方法中创建了一个NSLock。
以下是数据源的样子:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [results count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
[lock lock];
if (indexPath.row < [results count]) {
cell.textLabel.text = [results objectAtIndex:indexPath.row];
}
[lock unlock];
return cell;
}
以下是我用来更新表格的代码:
[tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
它完全解决了崩溃问题。但是,我认为它可能效率不高,因为每次要求一个单元格时,数据源都必须锁定/解锁。我上面提到的情况并不经常发生。有没有人更好地了解如何有效地解决这个问题?
非常感谢!
答案 0 :(得分:4)
不要尝试从后台线程更新UI。它不起作用。
答案 1 :(得分:2)
为什么要为此使用单独的线程?搜索需要多长时间? 0.1秒?这与用户停止输入并查看屏幕所花费的时间相比如何?
不要过于复杂化! (如果您的搜索时间超过0.7秒且无法优化,我会将其取回; - )
答案 2 :(得分:1)
这里有一个有用的答案,这是我对另一个类似问题的回答。
在不了解您的应用程序的情况下,我认为更好的解决方案之一是将数组保留在主线程上,并在另一个线程需要进行更改时将其分派回来。像这样:
dispatch_async(dispatch_get_main_queue(), ^{
[array addObject:object];
[tableView reloadData];
});
当然,使用调度API可以使事情变得更复杂,但它确实可以处理锁定和一切。绝对比使用NSLock更优雅。它只适用于iOS 4或更高版本。
答案 3 :(得分:0)