深入理解iOS API系列(五)dequeueReusableCellWithIdentifier:

Table Data Source Methods中的一个必要实现的方法tableView: cellForRowAtIndexPath: 中经常会包含一段代码:

static NSString *FirstLevelCell = @"FirstLevelCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
                             FirstLevelCell];
    if (cell == nil) {
        cell = [[UITableViewCell alloc]
                initWithStyle:UITableViewCellStyleDefault
                reuseIdentifier: FirstLevelCell];
    }


第一行是设置了一个字符串标识。

第二行起是关键,翻看官方文档中关于方法dequeueReusableCellWithIdentifier:的说明:

For performance reasons, a table view's data source should generally reuse UITableViewCell objects when it assigns cells to rows in its tableView:cellForRowAtIndexPath: method. A table view maintains a queue or list of UITableViewCell objects that the data source has marked for reuse. Call this method from your data source object when asked to provide a new cell for the table view. This method dequeues an existing cell if one is available or creates a new one using the class or nib file you previously registered. If no cell is available for reuse and you did not register a class or nib file, this method returns nil.

If you registered a class for the specified identifier and a new cell must be created, this method initializes the cell by calling its initWithStyle:reuseIdentifier: method. For nib-based cells, this method loads the cell object from the provided nib file. If an existing cell was available for reuse, this method calls the cell’s prepareForReuse method instead.

翻译一下 大意就是:

出于性能的原因,一个表视图的数据源应该采用可复用的表视图单元对象。一个表视图维护着一个可复用单元的队列或者列表。当要显示一个新的单元的时候就调用这个方法,这个方法会出列一个已经存在的单元。假如没有可以复用的单元那么就返回nil。

说实话不大清楚。还是从表视图的生命周期来说,一开始可复用队列为空,调用dequeueReusableCellWithIdentifier:肯定返回nil。然后就调用initWithStyle:reuseIdentifier:方法来产生并且标识复用记号的表视图单元。满屏显示的时候,滚动表视图,一侧的单元就会被移出屏幕,此时这个单元进入可复用单元队列,然后调用prepareForReuse方法准备一个即将出列的单元, dequeueReusableCellWithIdentifier:从可复用单元队列里出列一个可复用单元。

表视图里可能有不同类型的单元,复用是在相同类型单元里发生的。至于队列里有多少单元,这个系统自己控制,如果内存紧张,就会动态释放掉一些,当条件改善的时候,就会重新获取这些单元便于复用。一个极端的情况,可复用的单元没有了,那么又会调用initWithStyle:reuseIdentifier:来产生新的单元。理解表视图的机制,不能把思维定在严格的队列机制里,它有些动态的因素需要考虑。

此外在if语句下面的操作算是翻新,if语句里的操作应该是新造。

2021年8月24日更新

在iOS6的时候又多了一个类似的API:dequeueReusableCellWithIdentifier:forIndexPath:。后者会根据identifier从复用队列里获取对应的cell,并且根据indexPath获得高度,返回合适大小的cell。如果队列里没有合适的cell,则会根据registerNib:forCellReuseIdentifier: or registerClass:forCellReuseIdentifier: 来创建对应的cell,这两个方法要提前调用,否则dequeueReusableCellWithIdentifier:forIndexPath:会崩溃。因此这个API的特点是①必须register cell,②要设定indexPath以返回正确高度的cell。而dequeueReusableCellWithIdentifier:原来只会根据identifier从复用队列返回对应cell,没有的话返回nil。iOS6之后,如果register了cell的话,也会创建cell;没有register的话,最终返回nil。返回cell之后,后续还需要根据代理方法来设置高度。

关键参考:

http://blog.csdn.net/tongzhitao/article/details/7843897

apple官方文档

https://stackoverflow.com/questions/25826383/when-to-use-dequeuereusablecellwithidentifier-vs-dequeuereusablecellwithidentifi

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值