清除tableView单元格缓存(或删除条目)

时间:2010-03-08 14:45:17

标签: iphone uitableview

我遇到与此处所述相同的问题How to purge a cached UITableViewCell

但是“重置内容”无法解决我的问题。

准确地说 - 我使用自定义单元格(自己的类)。在运行应用程序时,我可能必须使用不同的“单元格类型”。 它是同一个类 - 但它有(很多)不同的属性。 当然我总是可以重置“PrepareForReuse”中的所有内容,但我认为这不是一个好主意(有很多东西需要重置)。

我的想法 - 我在单元格的构造函数中执行所有这些操作。 并且所有行将在稍后使用这种“类型的单元格”。 当(很少)情况出现时,我必须改变所有行的外观,我用不同的设置创建这种单元格的新实例。 现在我想用这个新单元替换排队的单元格。

我尝试使用相同的cellidentifier调用构造函数(希望它将替换现有的),但这不起作用。

我也没有找到“ClearReusableCells”或类似的东西。

有没有办法清除缓存 - 或删除/替换特定项目?

曼弗雷德

2 个答案:

答案 0 :(得分:2)

使用不同的标识符创建每个单元格类型(即使它们使用相同的单元格类)。因此,如果您有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;
}

答案 1 :(得分:0)

<强>更新

这不起作用。永远不会释放从dequeueReusableCellWithIdentifier返回的单元格的内存。

如果使用非零的reuseIdentifier初始化单元格,则在释放tableView本身之前不会释放该单元格。即使调用[[tableView valueForKey:@“reusableTableCells”] removeAllObjects],也是如此。不幸的是,tableView将单元格保留在其他私有成员中,释放它的唯一方法是销毁tableView。

简答

如何清除tableView单元缓存的问题标题的答案是Apple没有提供“ClearReusableCells”功能,但它自己实现起来相当容易。只需跟踪上次清除tableView缓存的时间并跟踪创建单元格的时间。如果单元格是在tableView的上一次缓存刷新时间之前创建的,则该单元格被认为是脏的。

<强>替代

  • Steven Canfield的答案 - 这是对特定问题的一个很好的答案,但如果有多个属性可以彼此独立地更改,则它不能很好地扩展。在这种情况下,您可以非常快速地拥有许多“模式”,并且可能无法管理。此外,关于内存使用情况,Apple代码确实负责管理内存,但是库也无法知道何时可能再次需要特定标识符,因此最终可能会保留这些缓存的单元格比它需要的时间更长。

  • 重新创建tableView - 这是一种强制机制,可以保证清除单元缓存。不幸的是,重新创建tableView通常很不方便。

  • Jake的Dahl从备用问题的回答 - 这是一个很好的机制,用于清除可能在编写时工作的缓存,但它依赖于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