优化UITableView性能

来源:互联网 发布:步步高家教下载软件 编辑:程序博客网 时间:2024/04/29 01:19

首先了解下UITableView的核心功能:UITableViewCell的重用机制。简单的说就是UITableView初次创建手机屏幕或者屏幕多一点点的UITableViewCell;每当cell滑出屏幕时,UITableView会将已创建的cell收录到一个集合中(数组或者字典),这个集合就相当于一个重用池;当要显示某一条cell时,会先从重用池中取,如果有的话直接拿来显示,没有则创建

了解重用机制后,在来关注下UITableView的两个回调方法:cellForRowAtIndexPath和heightForRowAtIndexPath;

理论来说UITableView会先调用前者,再调用后者,但事实并非如此。UITableView是继承自UIScrollView的,需要先确定它的contentSize及每个Cell的位置,然后才会把重用的Cell放置到对应的位置。所以事实上,UITableView的回调顺序是先多次调用heightForRowAtIndexPath:以确定contentSize及Cell的位置,然后才会调用cellForRowAtIndexPath:,从而来显示在当前屏幕的Cell。

举个例子来说:如果现在要显示100个Cell,当前屏幕显示5个。那么加载更多cell时,UITableView会先调用100次heightForRowAtIndexPath:方法,然后调用5次cellForRowAtIndexPath:方法;滚动屏幕时,每当Cell滚入屏幕,都会调用一次heightForRowAtIndexPath:、cellForRowAtIndexPath:方法。

下面分析下这段代码

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath  {      asd *cell = (asd *)[tableView cellForRowAtIndexPath:indexPath];      return cell.frame.size.height;  }  
注:高版本中会编译出错

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  {      NSString *identifier = [NSString stringWithFormat:@"%ld%ld",indexPath.row,indexPath.section];            asd *cell = [_table dequeueReusableCellWithIdentifier:identifier];      if(!cell){          cell = [[asd alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];      }      cell.label.text = identifier;      [cell setCellFrame];            return cell;  }
这样写法看似很巧妙,但只是简单cell,如果是复杂cell,直接卡到呵呵呵了...

根据上面的例子,我的优化思路是:因为 heightForRowAtIndexPath 先于 cellForRowAtIndexPath 调用。那么在 heightForRowAtIndexPath 的时候初始化 cell,缓存起来。
cellForRowAtIndexPath 的时候,从缓存读取。

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath  {      UITableViewCell *cell = [self customCreateCell:indexPath];      return cell.frame.size.height;  }  
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  {      return [self customCreateCell:indexPath];  }  
-(UITableViewCell *)customCreateCell:(NSIndexPath *)indexPath  {      NSString *identifier = [NSString stringWithFormat:@"%ld%ld",indexPath.row,indexPath.section];      //查找有没有缓存      asd *cell = (asd *)[_dataDic objectForKey:identifier];      if(!cell){          //没有的话调用tableView的重用机制          cell = [_table dequeueReusableCellWithIdentifier:identifier];          if(!cell){              cell = [[asd alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];          }          cell.label.text = identifier;          [cell setCellFrame];          [self.dataDic setObject:cell forKey:identifier];      }      return cell;  } 
0 0
原创粉丝点击