不要急,不要怕

cell的复用

cell创建的几种方式:

1.最常见的方法:

NoDataTbViewCell *cell =[tableView dequeueReusableCellWithIdentifier:@"noDataCell"];
    cell.delegate = self;
   if (cell==nil) {
       cell = [[NoDataTbViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"noDataCell"];
   }
   return cell;

2.注册:
先在给tableView设置delegate之前注册cell:

xib的:[self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([VideoTableViewCell class]) bundle:nil] forCellReuseIdentifier:VideoCell];

代码的: [self.tableView registerClass:[VideoTableViewCell class] forCellReuseIdentifier:VideoCell];

然后 cellForRowAtIndexPath:里

VideoTableViewCell *cell  = [tableView dequeueReusableCellWithIdentifier:identifier];

3.xib本地加载:

VideoTableViewCell *cell           = [tableView dequeueReusableCellWithIdentifier:identifier ];
   if (cell==nil) {
       cell = [[[NSBundle mainBundle] loadNibNamed:@"VideoTableViewCell" owner:self options:nil] lastObject];
       }    

cell复用原理:

说起复用就必须要说一下dequeueReusableCellWithIdentifier:这个函数,在iOS 6中dequeueReusableCellWithIdentifier:被dequeueReusableCellWithIdentifier:forIndexPath:所取代。如此一来,在表格视图中创建并添加UITableViewCell对象会变得更为精简而流畅。而且使用dequeueReusableCellWithIdentifier:forIndexPath:一定会返回cell,系统在默认没有cell可复用的时候会自动创建一个新的cell出来。但是使用dequeueReusableCellWithIdentifier:forIndexPath:的话,必须要和注册配合使用

dequeueReusableCellWithIdentifier消息返回的是UITableViewCell对象,即是说这是一个用来获取UITableViewCell对象的消息,之所以不说是初始化一个对象,是因为它可能返回nil值,所以才要在下面补充一个如果cell为nil时的处理过程。

那么这个方法是不是可以解释成为,从一个UITableViewCell对象池中获取一个以Identifier参数命名的UITableViewCell对象。
如果在资源紧缺的时候,这个池会自动清理多余的UITableViewCell对象,则可能无法返回对象,但如果资源丰富,则会保存一些UITableViewCell对象,在需要调用的时候迅速的返回,而不用创建。

dequeueReusableCellWithIdentifier,从字面上理解是“出列的可重用的cell”,其实简单说就是一个cell池,里面放的就是你之前创建过的cell。使用时要注意:
1。重取出来的cell是有可能已经捆绑过数据或者加过子视图的,所以,如果有必要,要清除数据(比如textlabel的text)和remove掉add过的子视图(使用tag。所以在给cell的模型赋值的时候一些逻辑最好放在if(cell==nil)里去执行.
2。这样设计的目的是为了避免频繁的 alloc和delloc cell对象而已,没有多复杂。
3。设计的关键是实现cell和数据的完全分离

关键点在”一个屏幕显示的cell数量”是有限的
当屏幕滚动时候,就会调用方法获取新的cell,而老的cell会在屏幕外面就不显示了

reuse机制就是这样。当cell需要显示的时候,从queue里面找,找到了,设置一下内容,显示出来
滚动界面当有cell被移出屏幕时,把这个cell丢到queue里面
显示新的cell时,如果有“相同类型”(identifier)的cell,就从队列拿一个出来,设置数据,显示出来
至于queue里面会有多少cell,这个会自动控制

要注意的是,queue里面存储的是cell的实例,不是“原型”
因此就会出现上面说的“假设每页有 5个。 则 第6个复用第1个cell; 第7个复用第2个;”
这样的结果是不管你的table有多少行,内存里实际上都只需要存储一个屏幕那么多行的cell就搞定了。。

部分链接

tableView的执行过程:

调用numberOfSection获得 A个 section
先调用numberOfRowsInSection获得B个cell,再调用heightForRowB次。如此循环A次
循环调用cellForRow和heightForRow,直到cell的个数充满当前屏幕。

附tableView代理方法表