iOS基础篇(十三)——UITableView(一)重用机制
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(一)重用机制的更多相关文章
- ios基础篇(十四)——UITableView(二)属性及基本用法
上一篇说了UITableView的重用机制,让我们对UITableView有了简单了解,下面说说UITableView的属性及常见方法. 一.属性 1.frame:设置控件的尺寸和大小 2.backg ...
- iOS学习笔记(4) — UITableView的 重用机制
iOS学习笔记(4) — UITableView的 重用机制 UITableView中的cell是动态的,在使用过程中,系统会根据屏幕的高度(480)和每个cell的高度计算屏幕中需要显示的cell的 ...
- iOS学习笔记(4)— UITableView的重用机制
UITableView中的cell是动态的,在使用过程中,系统会根据屏幕的高度(480)和每个cell的高度计算屏幕中需要显示的cell的个数.比如,cell高度为90.那么480 / 90 = 5 ...
- ios基础篇(二十八)—— UITableView的上拉加载
本文主要展示一个demo实现UITableView的上拉加载数据: 先看看效果图: 接着上拉,加载更多数据: 主要实现的效果是在我们上拉结束拖拽之后,开始加载数据,数据加载的过程中有滚动轮提示用户正在 ...
- ios基础篇(二十三)—— 定时器NSTimer与图片的自动切换
一.NSTimer NSTimer是一个能在从现在开始到后面的某一个时刻或者周期性的执行我们指定的方法的对象.可以按照一定的时间间隔,将制定的信息发送给目标对象.并更新某个对象的行为.你可以选择在未来 ...
- ios基础篇(二十六)—— UITableViewCell的分组索引与标记
一.表视图的索引目录 首先要创建一个TableView,之前有说过,这里就不详细说了(参考前面第十四篇). 直接贴代码吧, #import "ViewController.h" @ ...
- ios基础篇(十六)——UIWebView的基本使用
UIWebView是内置的浏览器控件,可以用它来浏览网页.打开文档等.UIWebView是一个混合体,具体的功能控件内置的,实现一些基本的功能.UIWebView可以查看Html网页,pdf文件,do ...
- J2EE基础篇——十三个规范
背景: 1.企业级应用框架的需求,在很多企业级应用中.比如数据库连接.邮件服务.事务处理等都是一些通用企业需求模块,这些模块假设每次在开发中都由开发者来完毕的话,将会造成开发周期长和代码可靠性差等问题 ...
- ios基础篇(十八)——Delegate 、NSNotification 和 KVO用法及其区别
一.Delegate Delegate本质是一种程序设计模型,iOS中使用Delegate主要用于两个页面之间的数据传递.iphone中常用@protocol和delegate的机制来实现接口的功能. ...
随机推荐
- EBS R12.2应用层关闭脚本的执行过程
$ pwd /app/oracle/apps/VIS/fs1/inst/apps/VIS_erptest/admin/scripts $ ./adstpall.sh apps/apps You are ...
- Leetcode: Longest Repeating Character Replacement && G 面经
Given a string that consists of only uppercase English letters, you can replace any letter in the st ...
- Python 集合操作
1.集合操作 集合是一个无序的,不重复的数据组合, 他的主要作业如下. 1.去重,把一个列表变成集合,就自动去重了 2.关系测试,测试两组数据之前的交集.差集.并集等关系 list_1 = [1,4, ...
- [技术分享] .NET下 , 上传图片的处理方式 , 贴上代码 .
如题 , 直接上单代码 , AC代码 <!DOCTYPE HTML> <html> <head> <meta charset="utf-8" ...
- _vimrc默认配置
"不使用兼容vi的模式set nocompatible source $VIMRUNTIME/vimrc_example.vimsource $VIMRUNTIME/mswin.vimbeh ...
- "Unity测试系列"文章索引
对Unity各种API的细节进行测试 Common 一些Unity基础操作的性能测试 Animation/Animator Animation Play/Stop测试 关于Animation动画事件的 ...
- iOS开发中的内存分配(堆和栈)
进程的内存分区 所有进程(执行的程序)都必须占用一定数量的内存,它或是用来存放从磁盘载入的程序代码,或是存放取自用户输入的数据等等.不过进程对这些内存的管理方式因内存用途不一而不尽相同,有些内存是事先 ...
- 【Python】我的Python学习笔记【2】【using Python 3】
... 1. 在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值, 所以,Python的函数返回多值其实就是返回一个tuple,但写起来更方便. 2. ...
- [问题2014S11] 复旦高等代数II(13级)每周一题(第十一教学周)
[问题2014S11] 设 \(A,B\) 为 \(n\) 阶实对称阵, \(p(A),p(B),p(A+B)\) 分别为 \(A,B,A+B\) 的正惯性指数, 证明: \[p(A)+p(B)\g ...
- LaTeX常用数学符号
之前在写博客做笔记时经常会在Word或WPS里写好数学公式再截图上传,一直觉得这样很low.现在实在是不想再去截图上传了,于是决定开始学一下LaTeX.在博客园中使用数学公式的设置可以参考在博客园使用 ...