dequeueReusableCellWithIdentifier的理解

来源:互联网 发布:如何评价香港 知乎 编辑:程序博客网 时间:2024/04/26 05:15

原博客地址:http://blog.csdn.net/tongzhitao/article/details/7843897

dequeueReusableCellWithIdentifier,首先我们从字面上理解一下,这个单词翻译一下就是“出列的可重用的cell”,其实简单理解来说就是一个cell池,里面放的就是你之前创建过的cell。

       iphone重用机制是苹果为了实现大量数据显示而采用的一种节省内存的机制,比如在UITableView和ScrollView 等地方。为什么要“可重用”?对于我们的项目来说,内存控制是必不可少的,如果一个tableview有几百个cell,这个内存消耗是很大的,而且有些cell里面都有image之类的很占内存的资源存在的话,那这样很容易出现memory warning甚至crash掉,这不是我们想要看到的。对此,tableview实现了它自己的管理方法dequeueReusableCellWithIdentifier(ps:我们在某些项目中scrollview来显示很多张image,在scrollview滑动中也要这样处理,来避免内存的过度消耗,只不过tableview它已经实现了这个方法,而不用我们自己去写)。

       reuse机制:当cell需要显示的时候,从queue里面找,找到了,设置一下内容,显示出来滚动界面当有cell被移出屏幕时,把这个cell丢到queue里面。显示新的cell时,如果有“相同类型”(identifier)的cell,就从队列拿一个出来,设置数据,显示出来。至于queue里面会有多少cell,这个会自动控制。 

其实也就是在"屏幕显示的cell数量"是有限的。当屏幕滚动时候,就会调用方法获取新的cell,而老的cell在屏幕外面就不显示了。

在使用TableView的时候,代码应该如何注意

[cpp] view plaincopy
  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {  
  2.       
  3.     static NSString *CellIdentifer = @"Cell";     //  0  
  4.       
  5.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Cell];      //   1  
  6.     if (cell == nil) {  
  7.         cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault  reuseIdentifier:CellIdentifer] autorelease];    //  2  
  8.     }  
  9.       
  10.     // Config your cell  
  11.      cell.textlabel.text = @"XXX";    //  3  
  12.       
  13.     return cell;  
  14. }  

可以这样理解,cell有一个地方(假设称为队列),专门存放那些生成过的,但是后来由于滚动tableView而隐藏起来的cell,而代码中语句1就是从队列中根据标示符取出一个暂时不用的cell,只有cell为nil,也就是队列中没有旧的cell的时候,才会执行语句2,生成一个新的cell。如果有旧的,就不用执行语句2了,这样节省资源,算作一种重用吧。在tableView初始化的时候队列中肯定没有cell的,所以每个cell生成的时候都会执行一遍2,当屏幕显示满了,向上滚动显示下一行时,就会把第一行隐藏,放到那个队列中,然后新增加的一行执行语句1的时候,结果就不是nil了,然后,就跳过语句2了,这样就节约资源了。

当然,上面这样对于使用系统提供的cell格式是没有什么问题,但是如果自己在cell上添加一些控件时,比如一个label,有时就会出现问题。尤其是各个cell的label的文字不相同时。首先这个添加的过程一定要在语句2之后,这样才是一次添加,如果放在语句3之后,那么由于cell的重用可能旧的上面已经有label了,你再添加一个,造成多次添加。其次label的文本值必须保证每次都要重新设置,也就是在语句3之后设置,这样才能保证每次必须执行。如果放在语句2后面,那么当使用旧的cell时,仍会保留旧的label文字,这是不对的。
所以是在2后添加,在3后设置,可以在2添加的时候设一个tag值,这样可以在3处通过tag值获取控件设置。

插句话:如果用自己做的Cell的话,可以在初始化的时候设置,在赋值的时候设置数据,跟上面的意思一样

关于语句0,如果每个cell的结构完全相同,那没问题,就用这一个标识符,但是如果各个cell结构不完全相同,有的有textfield,有的有button,有的有switch,那就不能互相重用了,只能每行用不同的标识符了,可以方便的利用(

NSString *CellIdentifier = [NSString stringWithFormat:@"%@%U_%U",@"Cell",indexPath.section,indexPath.row];

),保证不会重复,多组的再加上组号。那这还有必要用语句2吗?还是需要的,因为当自己滚动隐藏,下次再显示出来的时候,还是可以重用的。标识符完全可以每次用一个新的,但为了最大限度的重用性,节省资源,才想了这么多办法。

总之,注意添加控件的位置,注意设置控件的位置,注意cell标识符。

0 0
原创粉丝点击