2013-04-08 5 views
2

Я использую основные данные в своем приложении вместе с NSFetchedResultsController для заполнения таблицы. В моей базе данных есть записи 40k +, поэтому таблица довольно длинная. Каждая ячейка таблицы имеет уменьшенное изображение, которое загружается из Интернета с использованием SDWebImage. Все отлично работает, если я медленно прокручиваю, если я начну быстро прокручиваться через пару секунд, я получаю сбой.Определите, когда UITableViewCell освобожден

NSZombies не показывает ничего полезного.

Я предполагаю, что это связано с SDWebImage и загрузкой из Интернета. Путь SDWebImage работает, загружая изображение в фоновом режиме, затем устанавливая загруженное изображение после завершения загрузки (wordy). Моя мысль состоит в том, что ячейки освобождаются от UITableView, затем SDWebImage пытается установить изображение на освобожденную ячейку. Поэтому, если я могу определить, когда UITableViewCell будет освобожден, я могу остановить процесс загрузки SDWebImage и, надеюсь, исправить проблему.

Я пытался добавить

- (void)dealloc { 
    NSLog(@"dealloc"); 
} 

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

EDIT У меня есть -(void)dealloc метод в подклассе UITableViewCell.

EDIT Вот где/как создать ячейку

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
static NSString* inventoryCellID = @"InventoryCustomCellID"; 

InventoryCustomCell* cell = (InventoryCustomCell *)[tableView dequeueReusableCellWithIdentifier:inventoryCellID forIndexPath:indexPath]; 

[self configureCell:cell atIndexPath:indexPath]; 

return cell; 
} 


- (void)configureCell:(InventoryCustomCell *)cell atIndexPath:(NSIndexPath *)indexPath { 

    [cell formatCellWithProduct:[fetchedResultsController objectAtIndexPath:indexPath] enableAdding:NO]; 

    cell.openThumbnailButton.tag = indexPath.row; 

    [cell.openThumbnailButton addTarget:self action:@selector(presentThumbnailViewWithCell:) forControlEvents:UIControlEventTouchUpInside]; 
} 

В моей пользовательской ячейке это метод конфигурации называют:

- (void)formatCellWithProduct:(Product*)product enableAdding:(bool)addingEnabled { 

    self.titleLabel.text = product.part_number; 
    self.partNumberLabel.text = [[[product.manufacturer allObjects] objectAtIndex:0] name]; 

    //The SDWebImage UIImageView category method 
    [self.thumbImageView setImageWithURL:[NSURL URLWithString:product.photo] placeholderImage:[UIImage imageNamed:@"icon.png"]]; 
} 

EDIT Вот SDWebImage, который загружает изображение и устанавливает его.

- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock; 
{ 
    [self cancelCurrentImageLoad]; 

    self.image = placeholder; 

    if (url) 
    { 
     __weak UIImageView *wself = self; 
     id<SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) 
     { 
      __strong UIImageView *sself = wself; 
      if (!sself) return; 
      if (image) 
      { 
       sself.image = image; 
       [sself setNeedsLayout]; 
      } 
      if (completedBlock && finished) 
      { 
       completedBlock(image, error, cacheType); 
      } 
     }]; 
     objc_setAssociatedObject(self, &operationKey, operation, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 
    } 
} 
+0

Что такое инструменты, говорящие u? – vikingosegundo

+0

Потребовалось некоторое копирование, но обнаружил, что блок завершения на 'setImageWithURL' отправляется на освобожденный экземпляр. Таким образом, мои предположения были правильными, мне нужно найти способ получить уведомление о том, что ячейка освобождается от TableView. – random

+0

Пожалуйста, разместите этот блок. Из-за повторного использования ячеек вы не должны рассчитывать на сокрытие ячеек – vikingosegundo

ответ

12

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

Метод UITableViewDelegate-tableView:didEndDisplayingCell:forRowAtIndexPath: - лучшее место для обновления ячеек для отмены загрузки или других действий, не связанных с более длительным сроком действия.

Кажется, что каждый звонок -setImageWithURL:etc:etc: пытается отменить предыдущие загрузки для этого изображения.

+1

Ты, сэр, мужчина. Спасибо за помощь. – random

0

Вы не объяснить, где вы положили метод dealloc ..

Я считаю, вы можете попробовать добавить категорию к вашему ViewController для отладки только для тестирования, если открепление вашей ячейки называется (не той подкласс UITableviewCell).

Например:

@implementation UITableViewCell(Dealloc) 

- (void)dealloc { 
    NSLog(@"dealloc"); 
    [super dealloc]; 
} 

@end 

ли Вы использовать ARC? Если вы не забыли

InventoryCustomCell* cell = (InventoryCustomCell *)[[tableView dequeueReusableCellWithIdentifier:inventoryCellID forIndexPath:indexPath] autorelease]; 
+0

Я обновил свои вопросы, но у меня есть метод dealloc в подклассе UITableViewCell – random

+0

Показать, пожалуйста, метод cellForRow .. –

+0

Вопрос имеет был обновлен, спасибо за вашу помощь – random

Смежные вопросы