我有一个表格视图,其中填充了搜索词的结果。许多结果包含需要从 URL 加载的图像,但不是全部。我最初让它cellForRowAtIndexPath
在主线程的方法中从 URL 中抓取图像,效果很好,但是它使 tableview 的滚动变得断断续续,因为它暂时“卡”在每个图像上。
所以,我决定尝试在后台线程中加载图像。这是我的cellForRowAtIndexPath
方法。URL 存储在 resultsArray 中,索引对应于单元格的行。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
[sBar resignFirstResponder];
if (indexPath.row != ([resultsArray count]))
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ResultCell"];
UIImageView * bookImage = (UIImageView *)[cell viewWithTag:102];
//set blank immediately so repeats are not shown
bookImage.image = NULL;
//get a dispatch queue
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//this will start the image loading in bg
dispatch_async(concurrentQueue, ^{
NSData *image = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:[[resultsArray objectAtIndex:indexPath.row] thumbnailURL]]];
//this will set the image when loading is finished
dispatch_async(dispatch_get_main_queue(), ^{
bookImage.image = [UIImage imageWithData:image];
if(bookImage.image == nil)
{
bookImage.image = [UIImage imageNamed:@"no_image.jpg"];
}
});
});
return cell;
}
// This is for the last cell, which loads 10 additional items when touched
// Not relevant for this question, I think, but I'll leave it here anyway
else{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"More"];
UILabel *detailLabel = (UILabel *)[cell viewWithTag:101];
detailLabel.text = [NSString stringWithFormat:@"Showing %d of %d results", [resultsArray count], [total intValue]];
if ([UIApplication sharedApplication].networkActivityIndicatorVisible == NO) {
cell.userInteractionEnabled = YES;
}
return cell;
}
}
当 tableview 缓慢滚动时,图像都加载到相应的单元格中,我可以确认这一点,因为图像与单元格的标题匹配,但我忽略了除图像之外的所有设置以缩短此问题。但是,当我滚动得更快时,尤其是当我模拟慢速互联网连接时,图像开始加载到错误的单元格中。我认为这与重用单元格有关,因为如果我快速向顶部滚动,刚刚离开视图的单元格的图像通常会在刚刚进入的单元格中结束。我以为 bookImage.image = NULL; 行将确保不会发生这种情况,但我想不会。我想我不太了解后台线程,当最终从 URL 加载图像时,它是否忘记了它打算用于哪个单元?你知道会发生什么吗?感谢您的任何反馈!