理解Cell的注册与重用机制

##问题 在TableView中,我们经常需要加载非常非常多的Cell,每个Cell都有独立的内容。这时,如何才能保证你的TableView不会因加载过多Cell而挂掉呢?

Apple给出的解决办法是重用Cell

##Cell的加载与重用 TableView中维护着一个cell重用队列。当TableView第一次加载时,重用队列是空的。同时,TableView调用-(UITableViewCell *)tableView: cellForRowAtIndexPath:,用于加载屏幕可视区域中的Cell(注意噢!只加载可是区域的Cell)。iPhone可视区域有限,一般只能容纳15个左右的Cell。

当滚动TableView时,部分Cell会脱离可视区域。这些脱离了可视区域的Cell并不会被delloc销毁,而是放到重用队列中。

在滚动的同时,另一些新的Cell会进入可视区域。此时由于重用队列中存在可重用的Cell,因此TableView并不会alloc创建新的Cell,而是从重用队列中取出Cell,并给text,image等附上新的值,以供那些新进入可视区域的Cell使用。

开启重用机制

开启重用机制有两种方式:

1. 远古的手工办法(可用但不推荐)

这种做法的思路是: 每次TableView在请求需要一个可重用的Cell时,手工进行一次非空判断,如果存在可重用的Cell,则使用它,否则就alloc创建一个新的Cell。

static NSString *CellIdentifier = @"CellIdentifier";
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier];
    if(cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:SimpleTableIdentifier];
    }
    cell.textLabel.text = @"new text";
    return cell;
}

2. 使用注册机制开启重用机制

注册机制会对一种类型的Cell进行注册,注册的结果是:

  • 当TableView需要从重用队列中获取Cell,但重用队列为空时,则自动alloc创建新的Cell。
  • 当TableView需要从重用队列中获取Cell,且重用队列中有可重用的Cell时,TableView优先使用可重用的Cell,而不是创建新的Cell。

我们需要根据创建Cell的方式,选择正确的方法对cell进行注册和重用。下面讲到的三种创建cell的方式可参考自定义Cell的三种方式

####A. 使用纯代码创建cell 直接在代码中对cell注册。

//现在ViewDidload中注册
static NSString *CellIdentifier = @"CellIdentifier";
- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.tableView registerClass:[MyCell class] forCellReuseIdentifier: CellIdentifier];
    
//然后就不用判断可重用Cell是否为nil了
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
	MyCell *myCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
	myCell = @"new text";
	return myCell;
}

####B. 使用storyboard + 代码的方式 只需在storyboard中设置Cell的Identifier即可。需要注意的是,如果在使用了自定义cell,千万不要同时在storyboard和代码中对cell进行注册,这会造成cell渲染失败,一片空白。

####C. 使用xib + 代码 xib方式的cell只需在代码中注册即可。

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.dataSource = @[@"1", @"2", @"3"];
    
    UINib *nib = [UINib nibWithNibName:@"CellXib" bundle:nil];
    [self.tableView registerNib:nib forCellReuseIdentifier:CellIdentifier];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    MyCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    NSString *str = [self.dataSource objectAtIndex:indexPath.row];
    [cell setTheValue:str];
    return cell;
}

##Reference http://www.douban.com/note/232238166/

转载于:https://my.oschina.net/isingular/blog/618052

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值