




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、TableView 重用机制及常见问题 摘 要: IOS 是运行在苹果移动设备上的操作系统,它 对内存的控制比较严格。 Tableview 是在 IOS 开发过程中使 用的最为广泛的控件之一,常用来以列表的方式显示资料。 为了解决内存消耗问题, TableView 重用机制发挥着重要的 作用。本文对 TableView 重用机制进行了详细介绍,并指出 了开发过程中常见的问题。针对这个问题,本文给出了两种 解决方案,并通过内存消耗和 CPU 占有率这这个指标进行对 比,得出了第二种方案的更为有效的结论。 关键词: TableView 重用机制;内存消耗;解决方案 IOS 是由苹果公司为 ipho
2、ne 开发的操作系统。 它主要是 iphone、iPod touch以及iPad使用。就像 Mac OS X操作系统 一样,它也是以 Darwin 为基础的。 最新版的 IOS 系统( IOS8) 中,系统操作占用大概 1.1G 的内存空间 .后续的系统预计将 占用更多的内存。另外, IOS 设备提供给每个应用软件使用 的内存是有限的 1 。因此, IOS 对开发者进行内存管理的要 求很严格,对于易于崩溃、有内存泄露、以及内存占用量过 大的程序,都不能通过苹果公司的审核。因此, IOS 应用软 件的开发过程中,内存控制需要时刻注意。 1 TableView 的简介 TableView 是 AP
3、P 开发中使用率最高的一个常用控件, 基本上每个 view 都会见到它的身影。 TableView 功能很强大, 除了一般的表格资料展示之外,设置的属性资料往往也用到 TableView 。无论是 IOS 设备自带的通讯录、 备忘录、 提醒事 项等应用软件,还是第三方的微信、微博、陌陌等社交软件 2 ,都使用了这个视图。 TableView 继承自 ScrollView ,可 以表现为 Plain 和 Grouped 两种风格: Plain 样式指的是普通 的列表风格, 是方形的外观; Grouped 样式指的是分块风格, 主要以圆角形显示。 在 TableView 中的一行称为 TableV
4、iewCell ,而许多的 TableViewCell 组成了一个 TableSection,每个 TableSection 上下又分 ?e 有 Header 和 Footer ,许多个的 Table Section 则组 成了整个 Table , Table 也有 Header 和 Footer。TableViewCell 是 TableView 基本组成单元。 2 TableView 的重用机制 在 IOS 的一些视图中,它们的内部包含子视图,当父视 图显示区域发生变化时,比如用手滑动屏幕,原来在屏幕中 的子视图就会滑出到屏幕之外,而原来在屏幕之外的子视图 就有机会进入屏幕中 4 。就如上
5、文所述 TableView 常用于资 料的显示,如果一个 TableView 有几百个 TableViewCell ,根 据数据个数创建相应数量 TableViewCell ,会占用很大的内存 空间 3 。如果在 TableViewCell 里面含有 image 之类的很占 内存的资源,这就会造成应用程序在使用 TableView 加载大 批量数据时内存占用过大,那这样很容易出现内存警告甚至 崩溃掉,这不是我们想要看到的。因此, TableView 提供了 单元格重用机制来达到节省内存的目的:通过为每个单元格 指定一个重用标识符 ( reuseIdentifier ),即指定了单元格的种 类;
6、当单元格滚出屏幕时,允许恢复单元格以便重用。 TableView 自我管理的重用方法 dequeueReusableCellWithIdentifier ,这个方法列一个已经存在 的单元格, 假如没有可以重用的单元格那么就返回 nil 。合理 的使用重用机制会对程序的内存使用和优化都有很重要的 作用。 查看 TableView 头文件,会找 NSMutableArray *visiableCells 和 NSMutableDictnery *reusableTableCells 两个 结构。visiableCells 内保存当前显示的 cells, reusableTableCells 保存可
7、重用的 cells。 TableView 显示之初, reusableTableCells 为空,那么 tableView dequeueReusableCellWithIdentifier : CellIdentifier 返回 nil 。开始的 cell 都是通过 UITableViewCell alloc initWithStyle :UITableViewCellStyleDefault reuseIdentifier :CellIdentifier 来创建,而且 cellForRowAtIndexPath 只是调用最大显示 cell 数的次数。 比如:有 100 条数据, iphon
8、e 一屏最多显示 10 个 cell。 程序最开始显示 TableView 的情况是: 用UlTableViewCell alloc initWithStyle : UITableViewCellStyleDefault reuseIdentifier : CellIdentifier 创 建 10 次 cell ,并给 cell 指定同样的重用标识(当然,可以为 不同显示类型的 cell 指定不同的标识) 。并且 10个 cell 全部 都加入到 visiableCells 的队列, reusableTableCells 为空。 向上拖动tableView ,当celll完全移出屏幕,并且c
9、ellll 完全显示出来的时候。 cell11 加入到 visiableCells, cell1 移出 visiableCells , cell1 加入到 reusableTableCells。 接着向上拖动 tableView ,因为 reusableTableCells 中已 经有值, 所以, 当需要显示新的 cell, cellForRowAtIndexPath 再次被调用的时候, tableView dequeueReusableCellWithIdentifier :CellIdentifier ,返回 cell1 。 cell1 加入到 visiableCells , cell1
10、移出 reusableTableCells;cell2 移出 visiableCells , cell2 加入到 reusableTableCells。之后再需 要显示的 Cell 就可以正常重用了。 合理的使用重用机制会对 程序的内存使用和优化都有很重要的作用。 3 视图 重叠的问题 在 TableViewCell 中加入 TextField 或者 TextView 等子视 图,便可以在 cell 上进行文字编辑。 但对于多变的自定义 cell, 如当一个 cell 含有一个 UITextField 的子类并被放在重用队列 中以待重用,这时如果一个未包含任何子视图的 cell 要显示 在屏幕
11、上,就会取出并使用这个重用的 cell 显示在无任何子 视图的 cell 中,这个时候就会出现问题。 新建一个工程,在 .xib 绘制一个 TableViewCell ,在上面 显示“我是一个标签 N ”。核心代码如下: static NSString* mark = simpleIdentifier ; UITableViewCell* cell=tableView dequeueReusableCellWithIdentifier : mark ; if (! cell ) cell = UITableViewCell alloc initWithStyle : UITableViewCe
12、llStyleDefault reuseIdentifier : mark ; UILabel* label = UILabel alloc initWithFrame : CGRectMake ( 20, 12.0, 150, 20); label.backgroundColor = UIColor clearColor ; label.text = NSString stringWithFormat : 我是一个标 签%d, indexPath.row ; / 在 cell 上添加 label cell.contentView addSubview : label ; return cel
13、l ; 拖动 TableView ,如图 1 所示,多个视图出现重叠: 原因分析:拖拽视图,根据 TableView 重用机制,新滑 入的 Cell 会重用滑出的 Cell 空间,然后再 add 一个新的 Lable , 这样就会造成两个 Lable 文字的叠加,前面的文字变黑,后 面的数字叠加在一起。 4 UITableView 重用机制解决方案 为了解决重用机制下的上述问题,本文给出了两种解决 方案: 方案 1、在 cell 创建前,先把 subview 移除,从而得到 一个没有特殊格式的 cell ,供其他 cell 重用。 核心代码如下: static NSString* mark =
14、 simpleIdentifier ; UITableViewCell* cell=tableView dequeueReusableCellWithIdentifier : mark ; if (! cell ) cell = UITableViewCell alloc initWithStyle : UITableViewCellStyleDefault reuseIdentifier : mark ; / 获取 cell 上所有的子视图 NSArray* subviews = NSArray alloc initWithArray : cell.contentView.subviews
15、; for ( UIView* subview in subviews ) /移除子视图 subview removeFromSuperview ; UILabel* label = UILabel alloc initWithFrame : CGRectMake ( 20, 12.0, 150, 20); label.backgroundColor = UIColor clearColor ; label.text = NSString stringWithFormat : 我是一个标 签%d, indexPath.row; cell.contentView addSubview :labe
16、l; return cell ; 方案 2、在 TableViewCell 上添加一个 Label,将 Lable 固化在 Cell 上,设计效果如图 3 所示: 核心代码如下; static NSString* cellIdentify = TableCell ; UITableViewCell* cell = tableView dequeueReusableCellWithIdentifier :cellIdentify ; if (cell = nil ) /加载 XIB 中自定义的 cell cell = NSBundle mainBundle loadNibNamed : cell
17、Identify owner :self options:nil objectAtIndex :0; UILabel* label = (UILabel* ) cell.contentView viewWithTag :100 ; label.backgroundColor = UIColor clearColor ; label.text = NSString stringWithFormat : 我是一个标 签%d, indexPath.row; 运行,测试结果显示上述两种方法, 都可以将重叠的 bug 成功去除,效果如图 2 所示。 5 内存消耗分析 在程序设计的时候,只之所以使用 TableView 的重用机 制,是为了使用较少的内存。 比较上面两种方案如图 4 所示, 我们发现第二种方案其 CP
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论