• 一、分析:
  •     复用问题导致的现象:
  • 1、cell中数据赋值不成功。
  • 2、cell中数据赋值错乱。
  • 3、cell内赋值叠加。(本质即是cell内创建的控件叠加。多次创建造成的现象)。---最常见现象

二、这里分两种情况

1、系统的cell.

2、自定义cell.

三、情况分析

  • 首先我们分析系统的cell
  • 注意:系统的cell在实例化UITableView的时候,随即去注册一个cell:
  • [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"];
  • 这样写的话,如果你用这种代理方式去展示cell内容时

这时if(!cell){  }这个方法将不会被执行。对,你猜对了。这时cell是存在的。[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"];这句话已经注册了一个cell.所以它会在tableView的缓存池中去取。

此时你就不能在cell中添加一个label了。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
     if (!cell) {
         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
         UILabel *titleLabel = [[UILabel alloc] init];
         [titleLabel sizeToFit];
         titleLabel.tag = 100;
         titleLabel.frame = CGRectMake(170, 0, 50, 44);
         [cell.contentView addSubview:titleLabel];
     }
     cell.textLabel.text = [NSString stringWithFormat:@"%ld",indexPath.row];
     return cell;
 }

这就是这个结果      cell中数据赋值不成功。

@另一点你没有注册cell。要记得label的创建一定要放在if(!cell){   }这个作用域中。如果这时你放在作用域之外的话,每一次走代理方法的时候,都会创建一个label。这样label因为cell的复用,你在来回滚动的时候,label会越来越多的叠加。除非你写上这段代码:

for (id obj in cell.contentView.subviews) {
         if ([obj isKindOfClass:[UILabel class]]) {
             UILabel *lab = (UILabel *)obj;
             if (lab.tag == 100) {
                 lab.text = [NSString stringWithFormat:@"%ld",indexPath.row];
             }
         }
     }


这段代码定要放在你创建label代码之前,且不要放在if(!cell){   }这个作用域中。(放在label创建之后,你将会把你刚创建的label也移除,这样你的cell中就不会有任何的label控件了。如果放在if(!cell){   }这个作用域中,那么他只只有在cell不存在的时候才会去执行。也不能达到你想要的效果)

@如果你这样去写

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];

你就不要去写这些且必需注册cell

if (!cell) {
         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
         UILabel *titleLabel = [[UILabel alloc] init];
         [titleLabel sizeToFit];
         titleLabel.tag = 100;
         titleLabel.frame = CGRectMake(170, 0, 50, 44);
         [cell.contentView addSubview:titleLabel];
     }


这时,这段代码将不会被执行。

 

  • 然后我们分析自定义的cell
  • 用法和系统cell基本一样,但要注意下面一点

如果你自定义cell你的控件的创建尽量要放你cell的单独管理类中去创建,不要放在代理方法中会创建。这样就不会存在复用类的问题了。如果你硬要写代理 的方法中,你就要在你创建控件之前同样把你之前创建的控件先移除。避免造成复用。