02.1.1.tableView性能优化 - cell的重用

方法一

/**
 *  什么时候调用:每当有一个cell进入视野范围内就会调用
 */
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 0.重用标识
    // 被static修饰的局部变量:只会初始化一次,在整个程序运行过程中,只有一份内存
    static NSString *ID = @"cell";

    // 1.先根据cell的标识去缓存池中查找可循环利用的cell
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];

    // 2.如果cell为nil(缓存池找不到对应的cell)
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
    }

    // 3.覆盖数据
    cell.textLabel.text = [NSString stringWithFormat:@"testdata - %zd", indexPath.row];

    return cell;

方法二

tableView: cellForRowAtIndexPath:方法中有两个获得重用cell的方法

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]

  • 定义一个全局变量
// 定义重用标识
NSString *ID = @"cell";
  • 注册某个标识对应的cell类型
// 在这个方法中注册cell
- (void)viewDidLoad {
    [super viewDidLoad];

    // 注册某个标识对应的cell类型
    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:ID];
}
  • 在数据源方法中返回cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 1.去缓存池中查找cell
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];

    // 2.覆盖数据
    cell.textLabel.text = [NSString stringWithFormat:@"testdata - %zd", indexPath.row];

    return cell;
}

新的重用机制

- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(5_0);
- (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);
//需要使用dequeueReusableCellWithIdentifier:forIndexPath:注册的必须实现上面两个注册中的一种
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
}

http://www.07net01.com/program/565558.html

今天在学习IAP的时候无意间看到原来 
tableView: cellForRowAtIndexPath:方法中有两个获得重用cell的方法,
一直以来都是用
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
那下面的这个怎么用呢,感觉比较怪,假设没有重用的岂不是为空了
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]
具体有什么区别呢,
并且当我用 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]的时候,为什么总报错

reason: 'unable to dequeue a cell with identifier Cell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard',
经过查阅,知道原来此方法为6.0新加的,在SDK5.0是运行不起来的。 如果需要使用这个方法,你必须使用配套的方法来一起用,下面两个配套方法选其一:

- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(5_0); 
- (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);

比如你已经用NIB做了一个Cell,或者自定义了一个Cell。我们在你创建UITableView的时候,就可以顺带
self.tableView.backgroundColor = xxxx; 
[self.tableView registerClass:[CustomCell class] forCellReuseIdentifier:@"CustomCell"];

这样你在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath这个方法里,你就可以省下这些代码:
    static NSString *CellIdentifier = @"Cell"; 
 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];

     if (cell == nil) {         
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                reuseIdentifier:CellIdentifier];       
    //设置你的cell 
    }

而只需要
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
//设置你的cell 
    整体来说6.0却是比5.0更省劲

方法三

  • 在storyboard中设置UITableView的Dynamic Prototypes Cell

  • 设置cell的重用标识

  • 在代码中利用重用标识获取cell
// 0.重用标识
// 被static修饰的局部变量:只会初始化一次,在整个程序运行过程中,只有一份内存
static NSString *ID = @"cell";

// 1.先根据cell的标识去缓存池中查找可循环利用的cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];

// 2.覆盖数据
cell.textLabel.text = [NSString stringWithFormat:@"cell - %zd", indexPath.row];

return cell;

注意事项

重用的时候一些东西可能没清空 最好在赋值的时候把清空 重写

 -(void)setStatus:(Status *)status{ 
 _status = status;
 if (status.isVip) {
 self.nameLabel.textColor = [UIColor orangeColor];
 self.vipView.hidden = NO;
 } else {
 self.nameLabel.textColor = [UIColor blackColor];
 self.vipView.hidden = YES;
 }

 self.nameLabel.text = status.name;
 self.iconView.image = [UIImage imageNamed:status.icon];
 if (status.picture) {
 self.pictureView.hidden = NO;
 self.pictureView.image = [UIImage imageNamed:status.picture];
 } else {
 self.pictureView.hidden = YES;
 }
 self.contentLabel.text = status.text;

}

dequeueReusableCellWithIdentifier: forIndex: 方法是IOS6.0+版本才出现的,新的重用机制方法;只能在IOS 6.0以上系统才有效;

注意官方SDK说明: newer dequeue method guarantees a cell is returned and resized properly, assuming identifier is registered 即:使用dequeueReusableCellWithIdentifier: forIndex: 必须使用配套的

- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier

或者

 - (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier这个方法。对每一个tableview的cell进行注册。

results matching ""

    No results matching ""