如果每个单元格的内容都需要大量计算,那么保持 UITableView 平滑滚动的最佳方法是什么?例如:
#define maxN 40
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return maxN;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellId = @"CellIdentifier";
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:cellId];
//customization
int row = indexPath.row;
int fib = [self fib:row];
cell.textLabel.text = [NSString stringWithFormat:@"%d", fib];
return cell;
}
- (int)fib:(int)n
{
return (n<=2 ? 1 : [self fib:n-1] + [self fib:n-2]);
}
这适用于最大约 30 的 maxN。如果值大于该值,表格视图将在计算大数字时停止。
我知道解决方案与异步计算有关,但是您将如何设置它以保持 UI 流畅?
更新:这是更新的方法。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellId = @"FibIdentifier";
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:cellId];
[self configureCellAtIndexPath:indexPath];
return cell;
}
-(void)configureCellAtIndexPath:(NSIndexPath *)indexPath {
if ([self.fibResults objectAtIndex:indexPath.row] != [NSNull null]) {
// apply cached result
UITableViewCell *cell = [self.fibTable cellForRowAtIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat:@"%d", [(NSNumber*)[self.fibResults objectAtIndex:indexPath.row] intValue]];
return;
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(void){
NSInteger row = indexPath.row;
int fib = [self fib:row];
//cache the result
[self.fibResults replaceObjectAtIndex:row withObject:[NSNumber numberWithInt:fib]];
dispatch_async(dispatch_get_main_queue(), ^(void){
[self.fibTable reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
});
});
}
好消息是表格滚动流畅。坏消息是单元格填充了随机值,而不是正确的 1、1、2、3、5、8 等顺序。