2010-03-08 57 views
1

我有同样的问题,问题这里How to purge a cached UITableViewCell清除的tableView细胞缓存(或删除条目)

描述,但我的问题,不能以“重置内容”来解决。

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

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

我试着用相同的cellidentifier调用构造函数(希望它会替换现有的构造函数),但那不起作用。

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

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

曼弗雷德

+0

结帐我的回答类似的问题:http://stackoverflow.com/questions/2286669/iphone-how-to-purge-a-cached-uitableviewcell/15832337#15832337 –

回答

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; 
} 
+0

这确实还没有解决问题 - 当我打电话给tv.DequeueReusabelCell时,它将返回现在所做的事情。 我的问题是如何从该调用中获取新的单元格(不管是否相同或其他类)。 设置一个新的标识符将有助于 - 并产生孤儿:( – ManniAT

+0

首先感谢您的意愿来帮助我,以及您花费我的问题的时间 您在问我的问题在哪里: - 它是资源使用情况。我改变了我的模式 - 从那时起,电视缓存中出现了一个“重新使用”的单元格,但似乎Apple没有提供“清除机制” - 所以我想我必须接受这意味着我将进一步使用我当前的解决方案(这就像您也写了一样)更改了标识符 再次感谢Manfred – ManniAT

+0

从cellForRowAtIndexPath返回一个单元格后,由tableview来管理该内存。 tableView会在将来某个时候释放它,但这不是你关心的问题(一般情况下),只关心你提到的对象; –

0

更新

这是行不通的。从dequeueReusableCellWithIdentifier返回的单元内存从不释放。

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

简答

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

替代

  • 史蒂芬Canfield的答案 - 这是一个很好的回答的具体问题,但它并没有很好地扩展,如果有可以相互独立地改变多个属性。在这种情况下,你可以很快拥有很多'模式',并且可能无法管理。此外,就内存使用而言,确实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