您的位置:首页 > 产品设计 > UI/UE

UITableView dequeueReusableCellWithIdentifier

2014-12-26 16:21 399 查看
在使用UITableView控件的时候,datasource的代理方法经常会使用到下面的方法来加载UITableView的数据显示

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

{

    static NSString *CustomCellIdentifier = @"CustomCellIdentifier";

    DiscountProductCell * cell=  (DiscountProductCell*)[tableView dequeueReusableCellWithIdentifier:CustomCellIdentifier];

    if (cell == nil) {

        NSArray * nib = [[NSBundle mainBundle] loadNibNamed:@"DiscountProductCell" owner:self options:nil]
;

        cell = [nib objectAtIndex:0];

    } 

   cell.item = mPushItem;

   cell.selectionStyle = UITableViewCellSelectionStyleNone;

   UIImageView *backgroundView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"list"]] autorelease];

    cell.backgroundView = backgroundView;

    UIImageView *accessoryView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"ad1"]] autorelease];

    [accessoryView setFrame:CGRectMake(0.0f, 0.0f, CATEGORY_CELL_AC_WIDTH, CATEGORY_CELL_AC_HEIGHT)];

    cell.accessoryView = accessoryView;

    return cell;

}

代码中 DiscountProductCell * cell=  (DiscountProductCell*)[tableView dequeueReusableCellWithIdentifier:CustomCellIdentifier];是每个

cellForRowAtIndexPath方法都必须用到的。其中dequeueReusableCellWithIdentifier的意义是什么呢?

tableView实现是这样的,它并不创建所有行,比如你的表格数据有100行,但是屏幕上的空间只够显示10行,那么tableView只会创建10个左右的cell,当你滚动时,有些行会被遮住,这些被遮住的行就会被回收放入它的回收空间,而将要出现的行会首先在回收空间查找是否有空闲的cell,如果找到就使用,这样避免了创建cell带来的开销,节省空间和时间。这时的cell里的内容是旧的,你必需更新它的内容为将要出现的行的内容。

最近一直因为这个问题困扰着我,经过到处询问以及查询,终于弄明白些了,下面希望跟大家分享一下。
static NSString *CellTableIdentifier = @"CellTableIdentifier ";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
CellTableIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellTableIdentifier] autorelease];
}

4000

首先,先说一下重用是如何实现的,我们有一个很长的tableview,假设是100行,但在我们设计的行高情况下,屏幕只能显示10行,所以,当加载view的时候,实际只创建这10个cell,当我们用手指向上滑动即下方的第11个cell向上滑进界面的过程中,我们发现第一行的cell会滑出界面,当滑出后,第一行这个cell会被放到重用队列中,第11行将获得重用队列中的一个cell,这样,可以很好的控制内存。

在这段代码中 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellTableIdentifier]; 意思是定义一个cell,在tableview中的可重用队列中寻找有CellTableIdentifier标识的UITableViewCell,以进行重用。这个Identifier可以由我们自由定义成一些字符串。当然,如果在队列中有这样的UITableViewCell,那么则返回它给cell,若没有,则返回nil给cell。因为我们在写程序时经常需要用到好几个表格,每个表格中的cell布局都不一样,所以我们需要将在同一个表格的cell(布局一样)进行标记Identifier,这样,在重用的时候可以得到匹配的cell。

这时,就是下面的if语句了,若返回的是nil,即cell==nil,则我们需要分配空间并初始化一个cell,而且需要关联reuseIdentifier,以便后面重用的时候能够根据Identifier找到这个cell,若cell不为nil,则重用成功,并可return此cell。

当然,有些朋友说在重用的过程中,经常会有cell重叠的情况发生,这个很容易理解,因为cell滑出界面后并被放到重用队列时,cell中的内容并不会消失,我们可以通过多种方式解决,在此我主要是说明重用的机制,大家有这方面的问题可以在网上找一下解决方法。

这是我以前遇到的问题,那时候想既然书上是说这样做是用来重用的,那个identity就是他的ID啦,是根据ID来进行重用,那么ID就不能相同了,书在这方面都写得很笼统,一句就带过了。

自己修改了一下OK了,就没有在意里面是为什么,有代码就套代码就行了,明显是一个死程序员的做法。

今天看到你问了,我想了想里面的运行机制。

比如tableview有100行的数据,一打开的时候只能显示10条,如果你往下拉的时候,其实- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath这个方法是不断运行的。

你可以做一个断点在这个方法里,然后在测试的时候往下拉,都会停在这里。

也就是说往下拉,就会出现一个cell,而这个cell就是这个方法reture的cell。

打个比方容易了解,就像笔盒里最多只能放10支笔,而且这10支笔都不同颜色,我要放一支新的进去就要拿走里面一支。

tableview往下拉,就等同于我不断换笔盒里面的笔。

那如果我要换笔的笔芯,就根据他们的外形去拿这支笔出来,然后换了他。

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {

cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

}

这两行代码就说明了问题

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];这行代码就是根据ID在tableview里提取那个cell出来。

我们可以想到,第一次往下拉去提取cell,tableview是没有东西的,所以才会出来后面的if (cell == nil)去重新init这个cell。

然后再往上拉,也就是这个cell已经存在的时候,就从tableview里面根据ID去提取出来进行修改。

那我们可以再试想一下,如果我第一次读取这个cell的时候背景是红色,然后往上拉回去的时候要把它变为绿色,这种情况怎么写,我想大家应该清楚了吧。

把红色的代码放在if里面,把绿色的代码放在else if里面。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐