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){50,10,200,20}];
    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){50,10,200,20}];
    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]; 替换。

时间: 2024-11-07 05:54:01

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

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

iOS学习笔记(4) — UITableView的 重用机制 UITableView中的cell是动态的,在使用过程中,系统会根据屏幕的高度(480)和每个cell的高度计算屏幕中需要显示的cell的个数.比如,cell高度为90.那么480 / 90 = 5 + 1,也就是说最多有6个cell能显示在屏幕中. 系统会创建1个cel池,无论tableview有多少行都只创建6个cell放在池中.当某行移出屏幕的时候,将这个cell放回在池中:当某行需要显示在屏幕中时,从池中取出一个cell. 重

IOS 控件 - UITableView 的重用机制

转载来自:http://blog.csdn.net/joiningss/article/details/6702023 一. UITableView 的重用机制: iphone重用机制是苹果为了实现大量数据显示而采用的一种节省内存的机制,比如在UITableView和ScrollView 等地方.为什么要“可重用”???对于我们的项目来说,内存控制是必不可少的,如果一个tableview有几百个cell,这个内存消耗是很大的,而且有些cell里面都有image之类的很占内存的资源存在的话,那这样

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

一.NSTimer NSTimer是一个能在从现在开始到后面的某一个时刻或者周期性的执行我们指定的方法的对象.可以按照一定的时间间隔,将制定的信息发送给目标对象.并更新某个对象的行为.你可以选择在未来的某个时间将它停止.开启.甚至销毁. 1.NSTimer的创建 + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo

J2EE基础篇——十三个规范

背景: 1.企业级应用框架的需求,在很多企业级应用中.比如数据库连接.邮件服务.事务处理等都是一些通用企业需求模块,这些模块假设每次在开发中都由开发者来完毕的话,将会造成开发周期长和代码可靠性差等问题.于是很多大公司开发了自己的通用模块服务. 这些服务性的软件系列统称为中间件. 2.为了通用必需要提出规范,不然无法达到通用,在上面的需求基础之上,很多公司都开发了自己的中间件,但其与用户的沟通都各有不同,从而导致用户无法将各个公司不同的中间件组装在一块为自己服务.从而产生瓶颈. 于是提出标准的概念

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

一.Delegate Delegate本质是一种程序设计模型,iOS中使用Delegate主要用于两个页面之间的数据传递.iphone中常用@protocol和delegate的机制来实现接口的功能.例如想在A的功能要在B中实现,可以在A中定义一个Protocol. protocol用法: @interface ClassA :ClassB<protocol1, protocol2> 1.首先声明一个UIView类: @interface myView  :UIView{  } @end: 2

ios基础篇(九)——自定义UITabBar

上一篇讲到了UITabBarViewController,接着说说UITabBarViewController中怎么自定义TabBar. 今天仿写了微博,发现底部tabbar中间的button和其他有所不同,button较大且着色:而且我们平时工作中也有很多类似这样的问题,有些app有一个看起来像标准 tabBarController,但是呢,tabBar的中间是凸起的或者着色的.我们怎样做可以构建这种现实效果呢? 如图: 这些标签栏除了中间项以外看起来都相当的标准,所以我们会从一个标准的包含一

iOS基础篇(十五)——UIScrollView的基本用法

滚动视图(UIScrollView)通常用于显示内容尺寸大于屏幕尺寸的视图. 一.基本属性 1.CGSize contentSize :设置UIScrollView的滚动范围 2.CGPoint contentOffset :UIScrollView当前滚动的位置 3.UIEdgeInsets contentInset :设置内容的边缘 4.BOOL bounces 当超出边界时表示是否可以反弹 5.BOOL scrollEnabled 是否能滚动 6.BOOL showsHorizontalS

ios基础篇(二十七)—— Json解析

一.什么是Json JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于ECMAScript的一个子集. JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C.C++.C#.Java.JavaScript.Perl.Python等).这些特性使JSON成为理想的数据交换语言. 易于人阅读和编写,同时也易于机器解析和生成(一般用于提升网络传输速率). 1.Json的语法规则 (1)数据在键值对中 (2)数据由逗号分隔 (3

ios基础篇(三十)—— AFNetworking的使用

一.AFNetworking的创建 新建工程,命名为AFNDemo 二.导入AFNetworking.h AFNetworking文件下载:https://github.com/AFNetworking/AFNetworking 在ViewController.m中导入AFNetworking.h #import "ViewController.h" #import "AFNetworking.h" 1.创建一个下载任务(官方网站上给出的例子) NSURLSessi