UITableViewCell的重复利用机制有效地节省内存开销和提高程序性能。

1 原理

tableView拥有一个缓存池,存放未在使用(没有显示在界面)的cell。

tableView有一行cell要显示时先从缓存池里找,没有则创建,有一行cell隐藏不需要显示时就放到缓存池。

2 图解循环利用代码

//cellForRow 代码

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

  static NSString *ID = @"test"; // cell循环利用标识为”test”

  //从当前tableView对应的缓存池里找标识为”test”的cell;

  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];

  //如果缓存池里没有,即cell为空,创建新的cell

 if(!cell){

   cell = [[UITableViewCell alloc]init];

  }

  return cell;

}

3 循环利用问题

3.1 问题1

这里引入一个数据模型 LSUser(用户模型),

属性: name(NSString, 名字), vip(BOOL, 是否会员)

图3-1

//cellForRow方法中设置数据

//设置用户名称

cell.textLabel.text = user.name;

//如果用户是vip,设置用户名称颜色为红色

if(user.vip){

cell.textLabel.textColor = [UIColor redColor];

}

由于吴八不是会员,跳过if 语句,吴八名称颜色应为黑色,但实际上却保留着陈七cell0设置的会员颜色红色。这是循环利用一个简单的问题所在。

假设if 语句中添加了对称的设置语句,这个问题就不会出现。

if(user.vip){

cell.textLabel.textColor = [UIColor redColor];

}else{

cell.textLabel.textColor = [UIColor blackColor];

}

UITableViewCell的循环利用要求我们对称地设置视图的外观和状态。

实际上这个事例的循环利用问题可以认为出在cell.textLabel.textColor默认颜色为黑色上,假设需求是非会员名称颜色为蓝色,于是设置数据时:

cell.textLabel.textColor = user.vip ? [UIColor redColor]: [UIColor blueColor];

认真思考下。。。

3.2 问题2

这里有个需求:点击了某一行cell, 当前cell用户名称颜色改为紫色, 其余为原来的黑色

可能你会这么做:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

cell.textLabel.textColor = [UIColor purpleColor];

}

-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{

UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

 cell.textLabel.textColor = [UIColor blackColor];

}

暂时看来确实符合了需求,点击的当前行名称颜色为紫色,其余为黑色

但是,当你拖动tableView, 当前行隐藏,随意拖动,愕然地发现某一行名称颜色为紫色,再回到原先点击的当前行,名称颜色却为黑色而不是紫色。

这也是循环利用的问题。接下来解决这个问题。

当一行cell将要显示时,会调用tableView的数据源方法-tableView:cellForRowAtIndexPath;

循环利用影响影响cell显示,不会影响原始数据,该方法中进行了数据设置的步骤,利用它介绍两种解决方案:

1)  循环利用不会影响indexPath,indexPaht是唯一的。

  首先拥有一个NSIndexPath类型的selectedIndexPath属性,用于纪录当前选中行,在didSelectRowAtIndexPath方法中进行赋值。

  然后在-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath方法中,

  //设置数据

  //取出对应行的数据模型

  LSUser *user = self.users[indexpath.row];

  //设置用户名称

  cell.textLabel.text = user.name;

  //根据是否是选中行设置名称颜色

  if(self.selectedIndexPath == indexPath){
    cell.textLabel.textColor = [UIColor purpleColor];

  }else{

    cell.textLabel.textColor
= [UIColor blackColor];

  }

2)  对数据动手,从数据模型中派生一个专对于该cell的数据模型,追加相应的属性,然后在相应的地方对数据进行处理和设置。这里不再赘述,该方案适合处理复杂的情况,比如如不一定是选中与非选择两种状态,还可能是三种以上状态,或者cell的动画效果,或者需要[tableView reloadData]等的情况。

关于UITableViewCell的循环利用--面向初学者的更多相关文章

  1. 实现UITableView循环利用

    tableViewUITableView循环利用 前言 大家都知道UITableView,最经典在于循环利用,这里我自己模仿UITableView循环利用,写了一套自己的TableView实现方案,希 ...

  2. 解决cell循环利用造成的重复勾选

    @interface ProfessionViewController (){ NSMutableArray *_professionArray;//cell模型数组 NSMutableArray * ...

  3. iOS开发:一个瀑布流的设计与实现(已实现缓存池功能,该功能使得瀑布流cell可以循环利用)

    一个瀑布流的实现有三种方式: 继承自UIScrollView,仿写UITableView的dataSource和delegate,创造一个缓存池用来实现循环利用cell 写多个UITableview( ...

  4. iOS边练边学--UITableView性能优化之三种方式循环利用

    一.cell的循环利用方式1: /** * 什么时候调用:每当有一个cell进入视野范围内就会调用 */ - (UITableViewCell *)tableView:(UITableView *)t ...

  5. iOS开发小技巧--TableView中headerView的循环利用,以及自定义的headerView

    一.首先要搞清楚,tableView中有两种headerView,一个是tableHeaderView,另一个是headerView.前者就一个;后者根据session决定个数 headerView的 ...

  6. iOS开发UI篇—无限轮播(循环利用)

    iOS开发UI篇—无限轮播(循环利用) 一.无限轮播  1.简单说明 在开发中常需要对广告或者是一些图片进行自动的轮播,也就是所谓的无限滚动. 在开发的时候,我们通常的做法是使用一个UIScrollV ...

  7. [UGUI]滑动列表优化(循环利用)

    需要注意的有下面几点: 1. 区分好表现上的index和逻辑上的index.表现上的index是指这个go是go列表中的第几项,但实际上这个index的意义并不大,因为在滚动的过程中go列表是轮转的: ...

  8. [译]面向初学者的Asp.Net状态管理技术

    介绍 本文主要讲解Asp.Net应用程序中的状态管理技术(Asp.Net中有多种状态管理技术),并批判性地分析所有状态管理技术的优缺点. 背景 HTTP是无状态的协议.客户端发起一个请求,服务器响应完 ...

  9. 关于Java 实现抽象类的抽象方法的特性的利用---面向切面

    今天看工作看代码突然有了以下设想: /** * Created by zq on 2017/5/25. * 抽象类 */ public abstract class AbstractC { publi ...

随机推荐

  1. iOS开发核心语言Objective C —— 所有知识点总结

    C和OC对比 OC中主要开发在什么平台上的应用程序?答:可以使用OC开发Mac OS X平台和iOS平台的应用程序 OC中新增关键字大部分是以什么开头?答:OC中新增关键字大部分是以@开头 OC中新增 ...

  2. Git客户单for Windows

    1.GItHub for Windows  可参考:http://www.ihref.com/read-16514.html

  3. Oracle- UPDATE FROM讲解

    在表的更新操作中,在很多情况下需要在表达式中引用要更新的表以外的数据.像sql server提供了update的from 子句,可以将要更新的表与其它的数据源连接起来.虽然只能对一个表进行更新,但是通 ...

  4. 邮件Mail

    邮件开发准备: 准备工作, 环境搭建: 1. 本地搭建一个邮件服务器 -à 易邮服务器,eyoumailserversetup.exe 2. 新建邮箱账号 张三给李四发邮件. 步骤1: 新建域名: 工 ...

  5. 软件测试之WEB测试经典总结

    在Web工程过程中,基于Web系统的测试.确认和验收是一项重要而富有挑战性的工作.基于Web的系统测试与传统的软件测试不同,它不但需要检查和验证是否按照设计的要求运行,而且还要测试系统在不同用户的浏览 ...

  6. 域名的MX设置及校验方法

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  7. MFC 学习 之 状态栏的添加

    1.首先声明一个 CStatusBar  m_bar;//声明对象2.然后打开视图资源 String Table中添加两个字段值 3.创建了两个字段值以后,在OnintDialog() 所在的 .cp ...

  8. 转载:iPhone 6 Plus 屏幕宽度问题 375 vs 414

    首先看一张比较简单明了的 iPhone 6 与 iPhone 6 Plus 对比图,来自 PaintCode 的<The Ultimate Guide To iPhone Resolutions ...

  9. 【07】为多态基类声明virtual析构方法

    1.考虑下面的需要,需要一个工厂方法.工厂方法的规则是:在堆上分配一个子类对象,并返回父类指针.使用完毕,delete父类指针.如果父类的析构方法不是virtual,将直接调用父类的析构方法,导致局部 ...

  10. Upcase 将edit1中的每个字符串改为首字母大写

    //将edit1中的每个字符串改为首字母大写 procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);begin    with ...