У меня есть табличное представление, заполненное результатами поиска. У многих результатов есть изображения, которые нужно загрузить с URL, но не все. Первоначально у меня было захват изображения с URL-адреса в методе cellForRowAtIndexPath
в главном потоке, который работал отлично, но это сделало прокрутку просмотра таблицы прерывистой, так как она на мгновение «зависла» на каждом изображении.
Итак, я решил попробовать загрузить изображения в фоновом потоке. Вот мой cellForRowAtIndexPath
метод. URL-адреса хранятся в массиве результатов с индексами, соответствующими строке ячейки.
- (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;
}
}
Когда просмотр таблицы происходит медленно, все изображения загружаются в соответствующие ячейки, что я могу подтвердить, поскольку изображения соответствуют заголовкам ячеек, но я упустил настройку всего, кроме изображения, чтобы сократить его для этого вопроса. Однако, когда я прокручиваю быстрее, особенно когда я симулирую медленное интернет-соединение, изображения начинают загружаться не в те ячейки. Я думаю, что это как-то связано с повторным использованием ячеек, потому что, если я быстро прокручиваюсь к вершине, изображение ячейки, просто покидающей вид, часто оказывается в ячейке, только что входящей. Я думал, что bookImage.image = NULL; линия гарантировала бы, что этого не произойдет, но я думаю, что нет. Я думаю, я не очень хорошо понимаю фоновую многопоточность, когда изображение, наконец, загружается с URL, оно потеряло след, для какой ячейки оно было предназначено? Вы знаете, что может происходить? Спасибо за любые отзывы!