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

Iphone 清除tableView单元格缓存(或删除条目),iphone,uitableview,Iphone,Uitableview,我有和这里描述的相同的问题 但我的问题不能用“重置内容”来解决 准确地说,我使用一个自定义单元格(自己的类)。运行应用程序时,可能需要使用不同的“单元类型”。 它是同一个类,但有(许多)不同的属性。 当然,我总是可以在“prepareforeuse”重置所有东西,但我想这不是一个好主意(有很多东西需要重置) 我的想法-我在细胞的构造器中做所有这些事情。 所有行稍后都将使用这种“单元格类型”。 当(很少)出现我必须更改所有行的外观的情况时,我会创建一个具有不同设置的此类单元格的新实例。 现在我想用

我有和这里描述的相同的问题

但我的问题不能用“重置内容”来解决

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

我的想法-我在细胞的构造器中做所有这些事情。 所有行稍后都将使用这种“单元格类型”。 当(很少)出现我必须更改所有行的外观的情况时,我会创建一个具有不同设置的此类单元格的新实例。 现在我想用这个新的单元替换排队的单元

我试着简单地用相同的cellidentifier调用构造函数(希望它能替换现有的构造函数),但这不起作用

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

是否有办法清除缓存或删除/替换特定项

Manfred使用不同的标识符创建每个单元格类型(即使它们使用相同的单元格类)。因此,如果有两种单元格类型,请定义两个标识符并将它们分开

我不确定你的问题在哪里。您有一组单元格,外观为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;
}

更新

这不管用。从不释放从dequeueReusableCellWithIdentifier返回的单元格内存

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

简短回答

关于如何清除tableView单元缓存这一问题的标题,答案是苹果公司不提供“ClearReusableCells”功能,但它很容易自己实现。只需跟踪tableView缓存上次被清除的时间,并跟踪单元格创建的时间。如果单元格是在tableView的上次缓存刷新时间之前创建的,则认为该单元格是脏的

备选方案

  • Steven Canfield的回答——这是对特定问题的一个很好的回答,但如果存在多个可以独立更改的属性,则它的伸缩性不好。在这种情况下,您可以很快拥有许多“模式”,这可能会变得难以管理。另外,在内存使用方面,Apple code确实负责管理内存,但库无法知道何时可能再次需要某个特定的标识符,因此它很可能会将这些缓存单元保留得比需要的时间更长

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

  • Jake的Dahl对另一个问题的回答——这是一种很好的清除缓存的机制,可能在编写时就起作用了,但它依赖于一些苹果不保证的实现,事实上,这些实现已经改变了

实施 有多种方法可以跟踪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
@接口MyTableView:UITableView
@属性(非原子,赋值)NSTimeInterval cellCacheRefreshTime;
@结束
@接口MyTableViewCell:UITableViewCell
@属性(非原子,赋值)NSTimeInterval creationTime;
@结束
@实现MyTableView
-(void)刷新单元缓存{
self.cellCacheRefreshTime=[NSDate timeIntervalSinceReferenceDate];
}
-(id)dequeueReusableCellWithIdentifier:(NSString*)标识符{
MyTableViewCell*cell=(id)[超级出列可重用CellWithIdentifier:identifier];
if(cell.creationTime
这仍然不能解决问题-当我调用tv.DequeueReusabelCell时,它将返回它现在所做的。我的问题是如何从该调用中获取新单元(无论是同一类还是其他类)。设置一个新的标识符将有助于——并产生孤儿:(首先,感谢你愿意帮助我,感谢你花时间回答我的问题。你在问我的问题在哪里:-这是资源使用。我改变了我的模式-从那一刻起,“重-不再使用”手机挂在电视缓存中。但苹果似乎没有提供“清除机制”——所以我想我必须接受这一点。这意味着我将进一步使用我目前的解决方案(就像你也写的那样)标识符的更改。再次感谢Manfred。从cellForRowAtIndexPath返回单元格后,由tableview管理该内存。tableview将在将来的某个时候释放该内存,但这不是您的问题(一般)。只需担心您拥有的对象