dequeueReusableCellWithIdentifier不重用单元格

时间:2013-01-22 07:40:55

标签: iphone ios objective-c ipad uicollectionview

我有UICollectionView个自定义单元格子类UICollectionViewCell。在代码中我做了以下内容:

 [self.collectionView_ registerClass:[AHPinterestCell class]
        forCellWithReuseIdentifier:@"AHPinterestCell"];

这就是我的cellForItem

  AHPinterestCell *cell =
                (AHPinterestCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"AHPinterestCell"
                                                                             forIndexPath:indexPath];
然而,它似乎并没有重复使用细胞。在我的每个屏幕的集合视图中,它显示大约9-10个单元格,但是当我进行无限滚动然后我调用insertItemsAtIndexPath时,它会在我的自定义单元格上调用initWithFrame方法,而它应该重用细胞我已经有了。这是为什么?

修改

我正在添加一个说明问题的示例演示项目,可以找到xcode项目的链接here。它实际上是在你到达底部时进行无限滚动,它只是在其中添加更多内容。但是当你这样做时,它会再次调用init方法。

3 个答案:

答案 0 :(得分:4)

简而言之,您的代码运行正常。正如预期的那样,当单元格滚出屏幕时,它们最终会被标记为可以重复使用。当你拨打dequeueReusableCellWithReuseIdentifier时,如果有一个可以重复使用的小区,它就会这样做。如果没有,它会创建一个。

如果您快速或连续滚动,您将看到创建大量单元格的时间。但是如果你做一些简短的卷轴,放开,暂停,让UI赶上并重复,然后你会看到很少有细胞被创建。

我认为这意味着iOS优先考虑UI并创建新单元格而不是旧单元格的出列,从而允许它们重用。因此,如果你快速翻转,它就很难赶上并将旧单元标记为可重用。这可能并不完全是坏事,因为这可能是集合视图如此顺畅的流程。标记旧单元格以供重用是iOS在此处不太重要的事情之一。但显然如果内存紧张,这可能是一个问题。

顺便说一句,如果你在NSLog中放置一个dealloc,你会注意到当你在快速滚动浏览集合视图后最终赶上UI时,它显然有一些逻辑说“哎呀,我有更多的备用电池而不是我真正需要的电池,我将摆脱其中的一些。”实际上,这是一个非常聪明的实现。关注速度,但一旦UI安静下来,就会进行一些内存优化。

答案 1 :(得分:0)

同意,我有同样的问题,但我想创建一个类别,给我一个可见的单元格,如果有的话。

// Header file UITableView+VisibleCell.h"
@interface UITableView (VisibleCell)
- (UITableViewCell*) visibleCellForRowAtIndexPath:(NSIndexPath *)indexPath;
@end


// Implementation file UITableView+VisibleCell.m
#import "UITableView+VisibleCell.h"

@implementation UITableView (VisibleCell)

- (UITableViewCell*) visibleCellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    for( UITableViewCell* currentVisibleCell in self.visibleCells )
    {
        NSIndexPath* currentPath = [self indexPathForCell: currentVisibleCell ];
        if( [currentPath isEqual:(id) indexPath] )
        {
            return currentVisibleCell;
        }
    }    
    return nil;
}    
@end

你也可以从获取可见单元格然后返回cellForRowAtIndexPath而不是nil开始,这是一个样式问题。 (我需要这个来检索给定单元格中给定标记的UITextField,使其成为第一个响应者,但是cellForRowAtIndexPath不断重新分配我的单元格,非常令人沮丧。

答案 2 :(得分:0)

从设备设置中关闭辅助功能。 这是一个错误。 我在iPad mini上遇到了同样的问题。