Заполнение клеток TableView с использованием GCD

Я новичок в работе с GCD, и я боюсь понять, что то, что я здесь делаю, - это правильный способ сделать что-то.

Когда я настраиваю ячейку, я хочу извлечь URL-адрес из управляемого объекта, а затем отправить блок в GCD, чтобы вытащить уменьшенное изображение, которое находится по URL-адресу.

Как только загрузка изображений, я отправляю другой блок в первом блоке, который помещает загруженный значок в ячейку.

Когда таблица появляется на экране, я ожидаю увидеть счетчик активности в каждой миниатюре ячейки, после чего миниатюра впоследствии заменяется фактическим изображением после завершения загрузки.

На самом деле происходит то, что ячейки отображаются в TableView, и я не вижу счетчика. Если я нажимаю на ячейку, изображение появляется внезапно. Аналогично, если я перейду от этого представления, а затем снова отобразите его. Кроме того, когда я просматриваю TableView вверх и вниз, происходит что-то очень странное - миниатюры, кажется, "повторяются", а затем повторно загружаются при прокрутке.

Простите, если это немного сложно объяснить, но я не знаю, как лучше всего описать, что я вижу.

Я был бы признателен, если бы кто-нибудь мог взглянуть на код и, возможно, дать некоторые предложения относительно того, что может пойти не так:

if([managedObject isKindOfClass:[Photo class]])
{
 *********************** *spinner = [[*********************** alloc] ******************************:***********************StyleGray];
 [cell.imageView addSubview:spinner];
 [spinner startAnimating];
 Photo *photo = (Photo *)managedObject;
 NSString *URLString = photo.thumbnailURL;
 dispatch_queue_t callerQueue = dispatch_get_current_queue();
 dispatch_queue_t downloadQueue = dispatch_queue_create("Thumb downloader", NULL);
 dispatch_async(downloadQueue, ^{
 NSData *imageData = [FlickrFetcher imageDataForPhotoWithURLString:URLString]; 
 dispatch_async(callerQueue, ^{
 UIImage *thumbImage = [UIImage imageWithData:imageData];
 [spinner stopAnimating];
 cell.imageView.image = thumbImage;
 [cell.imageView setNeedsDisplay];
 });
 });
 dispatch_release(downloadQueue);
}
return cell;
2 ответа

Вы не должны напрямую обращаться к ячейке после фоновой загрузки данных (в данном случае изображения). Если он прокручивает экран перед загрузкой данных, он недействителен. Вы должны отключить механизмы по пути их загрузки данных, а когда он возвращает invoke [tableView reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation].


[cell.imageView addSubview:spinner];

Вышеприведенная строка не пахнет, как она будет работать. попробуйте [cell.contentView addSubview:spinner];. вам, скорее всего, придется изменить раскручиватель frame.origin, чтобы получить его в нужном месте.

миниатюры кажутся "повторяющимися", а затем снова загружаются при прокрутке.

Поскольку ваш tableViewCells повторно используется, загружаемое изображение не соответствует ячейке исходного запроса на выборку.

в вашем внутреннем, внутреннем блоке, вам нужно проверить, что ячейка по-прежнему соответствует управляемому объекту/фото/indexPath, который, как вы думаете, делает.

Разное:

  • Ваш счетчик утечки памяти.
  • после [spinner stopAnimating] вы, вероятно, захотите [spinner removeFromSuperview]

licensed under cc by-sa 3.0 with attribution.