У меня есть табличное представление, которое заполняется результатами поискового запроса. Многие из результатов содержат изображения, которые необходимо загружать с 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-адреса, не потеряло ли оно отслеживание того, для какой ячейки оно было предназначено? Вы знаете, что может происходить? Спасибо за любой отзыв!