我在寫一個App的時候自定義了一個UITableViewCell,可是這個UITableView在運行的時候出現了每6行數據就循環重複顯示的問題,而直接使用cell.textLabel.text顯示是沒有這個問題,如下是我實現的代碼。數組
- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- {
- NSInteger section = [indexPath section];
- NSInteger row = [indexPath row];
- UITableViewCell *cell;
- switch (section)
- {
- case 0:
- //do something.
- case 1:
- cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
- if (cell == nil)
- {
- cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"] autorelease];
- //Image
- UIImageView *p_w_picpath = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 14.0f, 45.0f, 50.0f)];
- p_w_picpath.backgroundColor = [UIColor clearColor];
- p_w_picpath.p_w_picpath = [UIImage p_w_picpathNamed:@"folder.png"];
- [cell.contentView addSubview:p_w_picpath];
- [p_w_picpath release];
- //Label
- UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(45.0f, 6.0f, 214.0f, 50.0f)];
- titleLabel.text = (NSString *)[(NSArray *)[self.categoryArray objectAtIndex:1] objectAtIndex:row];
- NSLog(@"%@ -- %d", titleLabel.text, row);
- titleLabel.textAlignment = UITextAlignmentLeft;
- titleLabel.numberOfLines = 3;
- titleLabel.tag = 201;
- titleLabel.font = [UIFont boldSystemFontOfSize:14];
- [cell.contentView addSubview:titleLabel];
- [titleLabel release];
- }
- cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
- break;
- }
- cell.selectionStyle = UITableViewCellSelectionStyleNone;
- return cell;
- }
google了一下,目前已有的解決方案是將ide
- cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
替換成函數
- cell = [tableView cellForRowAtIndexPath:indexPath];
或大數據
- cell = nil;
這們作的目的去掉Cell的重用機制,可是這種方法都會在後臺隨着表格滾動一直在建立cell,經過上面源代碼中Label定義裏那句NSLog在控制檯輸出就能夠看到,雖然會自動回收內存,但確定也會給系統帶來不小開銷,因此不到萬一得以仍是不會用的。google
還有一種解決方案是本身定義Cell數組,在tableView:tableView cellForRowAtIndexPath:中進設置要顯示的cell,這是手工維護cell的一種方式,對大數據量的狀況確定是不適用的,不過也能算得上是一種思路吧,能夠參考一下。其代碼以下:spa
- //在構造函數裏定義cell數組
- for(int i = 0; i < 31; i ++)
- {
- static NSString *MyBookMarkIdentifier = @"CityMangerCell";
- cityCell[i] = [[CityMangerCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyBookMarkIdentifier initIndex:i];
- }
- //使用它
- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- {
- if((0 <= indexPath.row) && (indexPath.row < 31))
- return cityCell[indexPath.row];
- return nil;
- }
後來我仔細分析了一下程序,找到了問題所在:xml
緣由是在if (cell == nil)判斷內部不該該對其label進行賦值,即不使用這句:內存
- titleLabel.text = (NSString *)[(NSArray *)[self.categoryArray objectAtIndex:1] objectAtIndex:row];
正確的作法應該是在if (cell == nil){}判斷後面進行賦值。即ci
- if (cell == nil)
- {
- ....
- }
- UILabel *l1 = (UILabel *)[cell.contentView viewWithTag: 201];
- l1.text = (NSString *)[(NSArray *)[self.categoryArray objectAtIndex:1] objectAtIndex:row];
分析緣由以下:
UITableView中被實例化的cell個數由屏高和每一個cell的高度決定,由於個人cell高度設置爲80,一屏只能 顯示6個Cell(只有6個cell被實例化),也就是隻有這6個cell纔會執行if (cell == nil){}中的代碼,從第6行日後的cell都是重用的這6個cell,也就是說從第7行開始將不會執行if (cell = nil){}中的代碼,當UITableView須要繪製第7行cell的時候,會取得第1個cell進行重用,若是咱們不把原來第1行cell中的 Label內容進行修改,那麼第7行將徹底顯示第1行中的內容,因此纔會在第6行以後開始出現數據重複的狀況。
如今我將Label內容設置的代碼放到if (cell == nil){}以後,它將會對每個被重用的cell的Label進行設定,也就不會再出現cell內容重複的現象。
但願這個問題的解決過程會對你們有所幫助。string