Очистить кеш ячейки tableView (или удалить запись) - PullRequest
2 голосов
/ 08 марта 2010

У меня та же проблема с вопросом, как описано здесь Как удалить кэшированный UITableViewCell

Но мою проблему невозможно решить с помощью «сброса содержимого».

Если быть точным - я использую собственную ячейку (собственный класс). При запуске приложения возможно, что мне придется использовать другой «тип ячейки». Это тот же класс, но у него есть (много) разных атрибутов. Конечно, я всегда мог сбросить все настройки в «PrepareForReuse», но я думаю, что это не очень хорошая идея (есть много вещей, которые нужно сбросить).

Моя идея - я делаю все эти вещи в конструкторе ячейки. И все строки будут использовать этот «тип ячейки» позже. Когда (редко) возникает ситуация, когда мне нужно изменить внешний вид всех строк, я создаю новый экземпляр ячейки такого типа с другими настройками. А теперь я хочу заменить ячейку в очереди на новую.

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

Я также не нашел "ClearReusableCells" или чего-то подобного.

Есть ли способ очистить кеш - или удалить / заменить определенный элемент?

Манфред

Ответы [ 2 ]

2 голосов
/ 08 марта 2010

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

Я не уверен, где твоя проблема. У вас есть группа ячеек с внешним видом A, затем пользователь выполняет некоторые действия, и они должны стать внешним видом B. Если вы вызовете reloadData или один из более гранулярных методов, ваш источник данных будет снова вызываться для cellForRowAtIndexPath. Просто реализуйте этот метод для разделения двух типов ячеек.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSString* identifier = which mode are we in
    UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:identifier]; // Will return nil if we haven't got this cell
    if( !cell ) {
        // Create different cell type based on the identifier   
    }
    return cell;
}
0 голосов
/ 22 октября 2014

Обновление

Это не работает. Память для ячейки, которая возвращается из dequeueReusableCellWithIdentifier, никогда не освобождается.

Если вы инициализируете ячейку с отличным от nil reuseIdentifier, то эта ячейка НЕ ​​будет освобождена, пока не будет освобожден сам tableView. Это верно, даже если вызывается [[tableView valueForKey: @ "reusableTableCells"] removeAllObjects]. К сожалению, tableView сохраняет ячейку в каком-то другом закрытом элементе, и единственный способ освободить ее - уничтожить tableView.

Короткий ответ

Ответ на заголовок вопроса о том, как очистить кеш ячеек tableView, заключается в том, что Apple не предоставляет функциональность «ClearReusableCells», но ее достаточно легко реализовать самостоятельно. Просто отследите время последней очистки кэша tableView и отследите время создания ячейки. Ячейка считается грязной, если она была создана до последнего времени обновления кэша tableView.

Альтернатива

  • Ответ Стивена Кэнфилда - Это хороший ответ на конкретный вопрос, но он плохо масштабируется, если есть несколько атрибутов, которые можно изменять независимо друг от друга. В этом случае вы можете очень быстро иметь много «режимов», и это может стать неуправляемым. Кроме того, в отношении использования памяти верно, что код Apple отвечает за управление памятью, но также верно и то, что библиотека не может знать, когда конкретный идентификатор может понадобиться снова, поэтому она, скорее всего, в конечном итоге будет хранить эти кэшированные ячейки дольше, чем нужно.

  • Воссоздать tableView - это механизм грубой силы, который гарантированно очищает кэш ячейки. К сожалению, воссоздать tableView обычно неудобно.

  • Ответ Джейка Даля на альтернативный вопрос - Это хороший механизм для очистки кэша, который, вероятно, работал во время его написания, но он опирается на некоторые реализации, которые Apple не гарантирует, и которые имеют в Факт уже изменился.

Осуществление Существует несколько способов отслеживания времени обновления кэша tableView и времени создания ячейки. Ниже показан механизм, который использует подклассы. Конечно, чтобы это работало, вам нужно убедиться, что код, который создает экземпляр таблицы и ячейки, создает экземпляры подклассов.

@interface MyTableView : UITableView
@property(nonatomic,assign) NSTimeInterval cellCacheRefreshTime ;
@end

@interface MyTableViewCell : UITableViewCell
@property(nonatomic,assign) NSTimeInterval creationTime ;
@end


@implemetation MyTableView

-(void) refreshCellCache {
    self.cellCacheRefreshTime = [NSDate timeIntervalSinceReferenceDate];
}

- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier {
    MyTableViewCell *cell = (id)[super dequeueReusableCellWithIdentifier:identifier] ;
    if( cell.creationTime < aTableView.cellCacheRefreshTime ) {
        return nil ; 
    }    
    return cell ; 
}

@end


@implemetation MyTableViewCell

-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier] ;
    self.creationTime = [NSDate timeIntervalSinceReferenceDate];
    return self ;
}

@end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...