当咱们下啦一个 UITableView时,若是没有作优化,只是简单的实现功能代码以下,这样当咱们有上百条tableviewcell的时候,咱们滑动的很是快时会很是费内存,固然苹果公司不会让咱们这样干,苹果公司会在程序启动加载页面的时候,只开辟出如今页面上的tableviewcell,剩下的就须要你滑动到该条才加载到内存中,已经划出的uitableviewcell则放到tableview内存池中,当下面须要这个类型的tableviewcell时就加载进去,iphone
UITableViewCell对象的重用原理 iOS设备的内存有限,若是用UITableView显示成千上万条数据,就须要成千上万个UITableViewCell对象的话,那将会耗尽iOS设备的内存。要解决该问题,须要重用UITableViewCell对象 重用原理:当滚动列表时,部分UITableViewCell会移出窗口,UITableView会将窗口外的UITableViewCell放入一个对象池中,等待重用。当UITableView要求dataSource返回UITableViewCell时,dataSource会先查看这个对象池,若是池中有未使用的UITableViewCell,dataSource会用新的数据配置这个UITableViewCell,而后返回给UITableView,从新显示到窗口中,从而避免建立新对象 还有一个很是重要的问题:有时候须要自定义UITableViewCell(用一个子类继承UITableViewCell),并且每一行用的不必定是同一种UITableViewCell(如短信聊天布局),因此一个UITableView可能拥有不一样类型的UITableViewCell,对象池中也会有不少不一样类型的UITableViewCell,那么UITableView在重用UITableViewCell时可能会获得错误类型的UITableViewCell 解决方案:UITableViewCell有个NSString *reuseIdentifier属性,能够在初始化UITableViewCell的时候传入一个特定的字符串标识来设置reuseIdentifier(通常用UITableViewCell的类名)。当UITableView要求dataSource返回UITableViewCell时,先经过一个字符串标识到对象池中查找对应类型的UITableViewCell对象,若是有,就重用,若是没有,就传入这个字符串标识来初始化一个UITableViewCell对象布局
<!-- lang: cpp --> UITableViewCell *tableViewCell = [tableView dequeueReusableCellWithIdentifier:@"ci"];
NSString *str = [NSString stringWithFormat:@"我是cell块——————%d",indexPath.row]; NSLog(@"%d------%p",indexPath.row,tableViewCell); tableViewCell.textLabel.text = str;性能
下面是优化好的代码:优化
<!-- lang: cpp -->ui
//
// pyViewController.m // 1128-05UITableView的优化设计 // // Created by panyong on 13-11-28. // Copyright (c) 2013年 panyong. All rights reserved. //spa
#import "pyViewController.h".net
@interface pyViewController ()<UITableViewDataSource,UITableViewDelegate>设计
@end @implementation pyViewController代理
// 返回cell的行数 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 70; }code
//返回cell -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //注意此处生成的cell的类型ci类型,ci能够随便写! UITableViewCell *tableViewCell = [tableView dequeueReusableCellWithIdentifier:@"ci"]; //这里我循环获得70行,注意内存哦!!!! NSString *str = [NSString stringWithFormat:@"我是cell块——————%d",indexPath.row]; if (tableViewCell == nil) { //tableview内存池,当有不用的tableviewcell划出屏幕时,就被回收到内存池中,而后,下面的tableviewcell从下面划出时是须要开辟tableviewcell的,因此如下tableviewcell先要判断类型reuseIdentifier是否是呵上面的tableviewcell相同,就好像一个病人要补充血液要找到本身合适的血型同样,若是相符就使用内存池里的,不果不相符系统从新开辟一个此种类型的tableviewcell 因此下面打印的时候地址是循环相同的,0---3都是不同的地址,而后才是重复0---3的地址!!!! tableViewCell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"ci"]; } //iphone官方加载机制是出现再屏幕上的内容(如tableViewCell)才加载,因此注意此处的打印!!!!一开始的时候因为我设置了cell的高度,一个3.5寸的屏幕只有显示三条cell, NSLog(@"%d------%p",indexPath.row,tableViewCell); tableViewCell.textLabel.text = str;
return tableViewCell;
}
//dele的一个方法返回cell的高度,该方法是实现协议UITableViewDelegate的方法
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 180;//这里为了方便演示效果,因此设置了cell的高度 }
@end
屏幕显示结果以下 打印内存结果以下,! 在此输入图片描述
其实咱们应该好好理解如下内存池的概念,苹果公司为了性能考虑,设计的这个理念!!!! tableViewCell.textLabel.text = str;这一句你能够放入内存池中试一下结果,呵呵,想清楚了吗????