UITableViewCell的重用机制原理

来自http://blog.csdn.net/omegayy/article/details/7356823

==========================================================

创建UITableViewController子类的实例后,IDE生成的代码中有如下段落:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = [NSString stringWithFormat:@"Cell"];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
//config the cell
return cell;
}

这里就涉及了TableView的重用机制,为了做到显示和数据分离,IOS tableView的实现并且不是为每个数据项创建一个tableCell。而是只创建屏幕可显示最大个数的cell,然后重复使用这些cell,对cell做单独的显示配置,来达到既不影响显示效果,又能充分节约内容的目的。下面简要分析一下它的实现原理。

重用实现分析

  查看UITableView头文件,会找到NSMutableArray*  visiableCells,和NSMutableDictnery* reusableTableCells两个结构。visiableCells内保存当前显示的cells,reusableTableCells保存可重用的cells。

  TableView显示之初,reusableTableCells为空,那么tableView dequeueReusableCellWithIdentifier:CellIdentifier返回nil。开始的cell都是通过[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]来创建,而且cellForRowAtIndexPath只是调用最大显示cell数的次数。

  比如:有100条数据,iPhone一屏最多显示10个cell。程序最开始显示TableView的情况是:

  1. 用[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]创建10次cell,并给cell指定同样的重用标识(当然,可以为不同显示类型的cell指定不同的标识)。并且10个cell全部都加入到visiableCells数组,reusableTableCells为空。

  2. 向下拖动tableView,当cell1完全移出屏幕,并且cell11(它也是alloc出来的,原因同上)完全显示出来的时候。cell11加入到visiableCells,cell1移出visiableCells,cell1加入到reusableTableCells。

  3. 接着向下拖动tableView,因为reusableTableCells中已经有值,所以,当需要显示新的cell,cellForRowAtIndexPath再次被调用的时候,tableView dequeueReusableCellWithIdentifier:CellIdentifier,返回cell1。cell1加入到visiableCells,cell1移出reusableTableCells;cell2移出visiableCells,cell2加入到reusableTableCells。之后再需要显示的Cell就可以正常重用了。

  所以整个过程并不难理解,但需要注意正是因为这样的原因:配置Cell的时候一定要注意,对取出的重用的cell做重新赋值,不要遗留老数据。

一些情况

  使用过程中,我注意到,并不是只有拖动超出屏幕的时候才会更新reusableTableCells表,还有:

  1. reloadData,这种情况比较特殊。一般是部分数据发生变化,需要重新刷新cell显示的内容时调用。在cellForRowAtIndexPath调用中,所有cell都是重用的。我估计reloadData调用后,把visiableCells中所有cell移入reusableTableCells,visiableCells清空。cellForRowAtIndexPath调用后,再把reuse的cell从reusableTableCells取出来,放入到visiableCells。

  2. reloadRowsAtIndex,刷新指定的IndexPath。如果调用时reusableTableCells为空,那么cellForRowAtIndexPath调用后,是新创建cell,新的cell加入到visiableCells。老的cell移出visiableCells,加入到reusableTableCells。于是,之后的刷新就有cell做reuse了。

UITableViewCell的重用机制原理的更多相关文章

  1. IOS中UITableViewCell的重用机制原理

    创建UITableViewController子类的实例后,IDE生成的代码中有如下段落: - (UITableViewCell *)tableView:(UITableView *)tableVie ...

  2. UITableViewCell的重用机制

    UITabelView一般会显示大量数据,如果有多少条数据就新建多少个cell,那么对于内存来说是种极大的负担,这样自然是不合理的,所以才会有重用机制 比如一个家庭办酒席,一共有13桌,每桌20个菜, ...

  3. UITableViewCell重用机制

    UITableView是iOS开发中使用频率非常高的一个控件,它常被用来展示信息列表,尽管信息数据可能非常多,但UITableView消耗的资源却并不会随着展示信息的增多而变大,这都要得益于UITab ...

  4. iOS - UITableView中Cell重用机制导致Cell内容出错的解决办法

    "UITableView" iOS开发中重量级的控件之一;在日常开发中我们大多数会选择自定Cell来满足自己开发中的需求, 但是有些时候Cell也是可以不自定义的(比如某一个简单的 ...

  5. iOS基础篇(十三)——UITableView(一)重用机制

    UITableView是app开发中常用到的控件,功能很强大,常用于数据的显示.在学习UITableView使用之前,我们先简单了解一下: 1.UITableView的重用机制 UITableView ...

  6. 从cellForRowAtIndexPath 看cell的重用机制

    今天突然发现一个问题,由于对UITableViewCell 的重用机制不是很了解,让我纠结很久: 用过reloadData时候,会调用cellForRowAtIndexPath方法,但是请看以下2种c ...

  7. 操蛋的UITableView重用机制

    1,背景 你可能会遇见一下情况: 使用UITableView加载数据,比如你的每一个cell上面有一个UITextField,当你在第一个cell的UITextField中写下了内容,开始下滑UITa ...

  8. IOS之TableViewCell重用机制解决上下刷新重复显示

    首先我是一个经验浅薄的iOS开发人员,这个问题想必许多初学者经常遇到这些问题,在面试中也会经常问到.现在我们一一解决. 首先我们要知道TableViewCell重用机制的原理是什么,我们抽象的理解为古 ...

  9. 【ios开发】UITableViewCell的重用

    移动开发需要解决的一个问题就是资源稀缺的问题.多数情况下是内存问题. 虽然现在的手机都号称大内存,高配置.但是移动app所占用的资源也在跟着不断膨胀, 也是造成内存不足的主要原因. 在前面的例子中,还 ...

随机推荐

  1. iOS-CALayer

    iOS开发UI篇—CAlayer层的属性 一.position和anchorPoint 1.简单介绍 CALayer有2个非常重要的属性:position和anchorPoint @property ...

  2. 安装Ubuntu 15.10后要做的事

    Ubuntu 15.10发布了,带来了很多新特性,同样也依然带着很多不习惯的东西,所以装完系统后还要进行一系列的优化. 1.删除libreoffice libreoffice虽然是开源的,但是Java ...

  3. EF - 批量插入

    比较一下下面两种方式的区别 1,每Add一次 就savechange() static void Main(string[] args) { //List<User> users= Fin ...

  4. iOS8 蓝牙设备的重连接(retrieve) Swift实现

    今天App写到了蓝牙重连的阶段,以前针对sdk 6.0写的代码,蓝牙设备的回复是通过 - (void)retrievePeripherals:(NSArray *)peripheralUUIDs 然后 ...

  5. 15.Cyclone II的IO资源学习

    IO资源 IO是与外界沟通和控制的通道,fpga提供了丰富的IO和一些实用的特性. 本文简要的将主要的特性摘录下来做设计参考用.具体参数参考handbook. 第一部分:IO特性概述 -----通过软 ...

  6. Min Stack

    Min Stack Design a stack that supports push, pop, top, and retrieving the minimum element in constan ...

  7. ubuntu 下root用户无法访问声音设备的解决方案

    原因:root用户没有对pulsaudio的访问权限,而且pulsaudio默认是不能在root下自动启动解决办法: 一.修改自动启动:编辑 gedit /etc/default/pulseaudio ...

  8. Java小应用程序

    Java小应用程序: package applet;   import java.applet.AudioClip; import java.awt.BorderLayout; import java ...

  9. android 系统应用在运行时被卸载

    android 系统应用在运行时被rm 掉了,是否还会运行? 环境:root,且开机运行 经过试验,apk本身是在 /system/app 目录下面,且apk已经运行了,这个时候直接 rm /syst ...

  10. How to Build Android Applications Based on FFmpeg by An Example

    This is a follow up post of the previous blog How to Build FFmpeg for Android.  You can read the pre ...