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

1、UITableView的重用机制

UITableView最核心的思想就是UITableViewCell的重用机制,对于一个UITableView而言,可能需要显示成百上千个Cell,如果每个cell都单独创建的话,会消耗很大的内存,为了避免这种情况,重用机制就诞生了。

UITableView的重用机制的实现关键在于下面这个的函数:UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];首先,我们要清楚这一点,这个函数是做什么的,它的文档说明如下:
returns a reusable table-view cell object located by its identifier。它返回的是一个受identifier管理定位的可重用的tableViewCell,这里重点就在于“可重用”这3个字上。

假设某个UITableView有100个数据需要显示,即需要100个Cell,然而屏幕中最多只能一次性显示10个Cell,那么有一个办法可以不用创建100cell,而只需要创建(10+1)个;

滑动 tableview 的时候,刚离开视图的 cell 会被放到复用池 中,等下一个 cell需要 显示时,会先看复用池中有没有 cell 如果有的时候 ,就从复用池中拿出来cell ,没有的话就重新创建cell 。如下代码:

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

创建UITableViewCellStyleDefault类型的cell,并将其标识为identifier;这样一个cell就创建完成了。当需要第2个cell的时候,同样也是先从重用队列里去取,发现还是没有,那么继续创建。可想而知,刚进到这个页面的时候需要创建10个cell,且他们的标识符都是identifier。

当我们下拉tableView,我们知道会出现第11个cell。这个时候还是先从重用队列里去取,发现没有,继续创建第11个cell并返回,这个时候,当第11个cell完全显示出来,第1个cell也刚好完全消失,这样第一个cell(标记为cell1)被放进重用队列了”。

再继续下拉,就要出现第12个cell了,同样的,还是要先调用dequeueReusableCellWithIdentifier:方法,从重用队列中寻找cell,这个时候队列中有cell1,就会被取出来,这时候if(!cell)条件不成立,也就不会创建新的cell了,这个cell被返回作为第12个cell,当第12个cell完全显示,第2个cell就完全消失进入重用队列了。可想而知,在13、14...也是如此,所以说,尽管需要100个cell,实际上只需创建11个cell,这就是重用机制。

2、列表的重复混乱问题

- (UITableViewCell *)tableView:(UITableView *)tableView_ cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    static NSString *reuseIndentifier = @"UITableViewCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIndentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIndentifier];
}
UILabel *label = [[UILabel alloc]initWithFrame:(CGRect){,,,}];
label.text = [NSString stringWithFormat:@"第%d行",(int)indexPath.row];
[cell addSubview:label]; return cell; }

我们在每个cell中添加了一个label,运行,下拉,我们会发现如下现象:

这是因为每次新出现的cell都是之前用过的,再对它添加label就是在原来基础上又添加了一次,所以会出现上图所示列表混乱的现象。怎么解决这种现象呢?

方法一:在建立新的label之前,把之前创建label移除

- (UITableViewCell *)tableView:(UITableView *)tableView_ cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    static NSString *reuseIndentifier = @"UITableViewCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIndentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIndentifier];
} //移除所有子视图
[cell.subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
UIView *view = (UIView*)obj;
[view removeFromSuperview];
}]; //添加新视图
UILabel *label = [[UILabel alloc]initWithFrame:(CGRect){,,,}];
label.text = [NSString stringWithFormat:@"第%d行",(int)indexPath.row];
[cell addSubview:label]; return cell; }

方法二:这种方法放弃了重用机制,每次根据indexPath获取对应的cell返回。

将方法:  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIndentifier];

用方法:  UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 替换。

iOS基础篇(十三)——UITableView(一)重用机制的更多相关文章

  1. ios基础篇(十四)——UITableView(二)属性及基本用法

    上一篇说了UITableView的重用机制,让我们对UITableView有了简单了解,下面说说UITableView的属性及常见方法. 一.属性 1.frame:设置控件的尺寸和大小 2.backg ...

  2. iOS学习笔记(4) — UITableView的 重用机制

    iOS学习笔记(4) — UITableView的 重用机制 UITableView中的cell是动态的,在使用过程中,系统会根据屏幕的高度(480)和每个cell的高度计算屏幕中需要显示的cell的 ...

  3. iOS学习笔记(4)— UITableView的重用机制

    UITableView中的cell是动态的,在使用过程中,系统会根据屏幕的高度(480)和每个cell的高度计算屏幕中需要显示的cell的个数.比如,cell高度为90.那么480 / 90 = 5  ...

  4. ios基础篇(二十八)—— UITableView的上拉加载

    本文主要展示一个demo实现UITableView的上拉加载数据: 先看看效果图: 接着上拉,加载更多数据: 主要实现的效果是在我们上拉结束拖拽之后,开始加载数据,数据加载的过程中有滚动轮提示用户正在 ...

  5. ios基础篇(二十三)—— 定时器NSTimer与图片的自动切换

    一.NSTimer NSTimer是一个能在从现在开始到后面的某一个时刻或者周期性的执行我们指定的方法的对象.可以按照一定的时间间隔,将制定的信息发送给目标对象.并更新某个对象的行为.你可以选择在未来 ...

  6. ios基础篇(二十六)—— UITableViewCell的分组索引与标记

    一.表视图的索引目录 首先要创建一个TableView,之前有说过,这里就不详细说了(参考前面第十四篇). 直接贴代码吧, #import "ViewController.h" @ ...

  7. ios基础篇(十六)——UIWebView的基本使用

    UIWebView是内置的浏览器控件,可以用它来浏览网页.打开文档等.UIWebView是一个混合体,具体的功能控件内置的,实现一些基本的功能.UIWebView可以查看Html网页,pdf文件,do ...

  8. J2EE基础篇——十三个规范

    背景: 1.企业级应用框架的需求,在很多企业级应用中.比如数据库连接.邮件服务.事务处理等都是一些通用企业需求模块,这些模块假设每次在开发中都由开发者来完毕的话,将会造成开发周期长和代码可靠性差等问题 ...

  9. ios基础篇(十八)——Delegate 、NSNotification 和 KVO用法及其区别

    一.Delegate Delegate本质是一种程序设计模型,iOS中使用Delegate主要用于两个页面之间的数据传递.iphone中常用@protocol和delegate的机制来实现接口的功能. ...

随机推荐

  1. SQL Server错误与事务处理

    T-SQL中出现的错误,依据和事务的关系,可以分为两种情况: 有的错误会导致发生错误位置之后的代码不再执行,如果错误位置在事务中,该事务也会自动回滚(即在错误位置之后的rollback语句不会执行,但 ...

  2. iptables nt

    占位... 扩展 1.其实匹配扩展中,还有需要加-m引用模块的显示扩展,默认是隐含扩展,不要使用 -m 状态检测的包过滤-m state       --state {NEW,ESTATBLISHED ...

  3. JAVA:NIO初步了解

    简介: Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作方式. Java NIO: Ch ...

  4. Linux下使用shell实现上传linux下某个目录下所有文件到ftp

    首先我们需要搞清楚单个文件怎么上传,把这个单文件上传到ftp上的实现命名为一个:upload_to_ftp_command.sh 之后,需要弄清楚怎么实现遍历一个目录下的所有文件的,把这个遍历某个目录 ...

  5. Leetcode: Non-overlapping Intervals

    Given a collection of intervals, find the minimum number of intervals you need to remove to make the ...

  6. array_merge注意细节

    array_merge:合并一个或多个数组,一个数组中的值加在前一个数组的后面,返回的新数组作为结果 如果输入的数组中有相同的字符串键名,则该键名后面的值覆盖前面的,如果数组包含相同的数字键名,后面的 ...

  7. json学习小记

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  8. [已解决] MyBatis 中bind用法

    JAVA: TC_ENTR_FLOW selectFlowForUpdate(String ENTR_ID); XML: <select id="selectFlowForUpdate ...

  9. visual studio 引用lib

    方法1: 要具有lib文件和.h文件 1.加入语句 #pragma comment(lib, 'C:\\test\\Debug\\test.lib' 2.项目右键-〉属性-〉c++ -〉常规-〉附加包 ...

  10. javascript 函数声明和函数表达式的区别(学习笔记)

    javascript中声明函数的方法有两种:函数声明式和函数表达式. 区别如下: 1).以函数声明的方法定义的函数,函数名是必须的,而函数表达式的函数名是可选的. 2).以函数声明的方法定义的函数,函 ...