問題描述:
在使用UITableView時,我們習慣在tableView:cellForRowAtIndexPath:方法中使用CocoaTouch提供的表格單元格緩存來重用單元格:
static NSString* cellid=@"exTable_cellid";
UITableViewCell* cell=(UITableViewCell*)[tableView
dequeueReusableCellWithIdentifier:cellid];
if (cell==nil) {
cell=[[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:cellid]autorelease];
UILabel *lblName[[UILabel alloc]initWithFrame:
CGRectMake(20, 6, 100, 20)];
……
}
表面上看這沒有任何問題。但對于可折疊分組的表格,則會導緻一系列問題。原因在于Cocoa Touch提供的單元格緩存無法識别不同的組(section),對它來說,第1個section的第1行,和第2個、第3個…第n個section的第1行都是一樣的。于是,當你打開了第1個section後,再打開其他的section,會發現,所有的section的前面幾行全都變成了第1個section中的内容,例如在一個折疊分組表格中,我們先打開一個section:

然後再打開其他的section,發現,所有的section下的第1行内容都變成了zhangsz:
既然問題提出了,讓我們來看看解決的方法。
解決辦法:
解決的辦法有兩個,一是不使用Cocoa Touch的單元格緩存,即每次都重新建構UITableViewCell:
//這裡不采用重用方式,每次重新整理都重新構造cell。對于分組表格,重用cell會導緻一些問題
// static NSString*cellid=@"exTable_cellid";
UITableViewCell* cell=[[UITableViewCell alloc]initWithFrame:CGRectMake(0, 0, self.frame.size.width,rowHeight)];
UILabel *lblName[[UILabel alloc]initWithFrame:
CGRectMake(20, 6, 100, 20)];
……
這裡我們采用了UITableViewCell的另外一個初始化方法來建構單元格,這個方法不需要傳遞reuseIndentifier參數,即不使用單元格緩存。這種方法簡單有效,但由于每次重新整理表格時都會重新構造單元格,與重用單元格緩存比較而言,會導緻額外的性能開銷。
第二種方法,是使用tag屬性和viewWithTag方法。這種情況下可以使用單元格緩存,同時避免了前面所述問題的出現:
static NSString* cellid=@"exTable_cellid";
UITableViewCell* cell=(UITableViewCell*)[tableView
dequeueReusableCellWithIdentifier:cellid];
if (cell==nil) {
cell=[[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:cellid]autorelease];
UILabel *lblName[[UILabel alloc]initWithFrame:
CGRectMake(20, 6, 100, 20)];
lblName.tag=1022;
[cell addSubView:lblName];
……
}
lblName=[cellviewWithTag:1022];
lblName.text=… …
… …
聰明的你,是不是還想到了其他的辦法呢?比如擴充自己的UITabelViewCell子類?