【问题标题】:dequeueReusableCellWithIdentifier never returns nildequeueReusableCellWithIdentifier 从不返回 nil
【发布时间】:2013-05-05 06:40:48
【问题描述】:

我在 UITableView 中使用了自定义 UITableViewCell,但问题是在调用 dequeueReusableCellWithIdentifier 时单元格永远不会为零。这是为什么呢?

- (void)viewDidLoad
{
    [super viewDidLoad];
    UINib *nib = [UINib nibWithNibName:@"PHResultTableViewCell" bundle: nil];
    [[self tableView] registerNib:nib forCellReuseIdentifier:@"MyCell"];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath     *)indexPath
{
    PHResultTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell"];
    if (cell == nil)
    {
        PackageHolidayItem *obj=[[PackageHolidayItem alloc]init];
        obj= [totalArray objectAtIndex:indexPath.row];
        cell.packageHolidayItem = obj;
        [cell loadRow];

    }
    return cell;
}    

【问题讨论】:

  • 你在使用故事板吗?
  • 即使你没有注册 nib 并且 dequeueReusableCellWithIdentifier 可以返回 nil,仅在 if (cell == nil) { ... } 情况下配置单元格也是错误的。

标签: ios uitableview


【解决方案1】:

从 iOS 5 开始,当您使用故事板并且您的重用标识符与故事板中的原型匹配时,您将不会从 dequeueReusableCellWithIdentifier 返回 nil。

来自 Apple 文档:

iOS 表格视图编程指南

创建和配置表格视图

用数据填充动态表视图

如果 dequeueReusableCellWithIdentifier: 方法要求一个单元格 在故事板中定义的,该方法总是返回一个有效的 细胞。如果没有一个回收的cell等待被重用,该方法 使用情节提要本身的信息创建一个新的。这 无需检查 nil 的返回值并创建一个 手动单元格。

您可以记录手机地址以向您自己证明它们正在被重复使用。但是不要附带日志,它会真正减慢你的表。

NSLog(@"Deque Cell %p", cell);

最好使用断点来记录它。

$25 = 0x097f9850 <DDSImageSubtitleCheckedTableViewCell: 0x97f9850; baseClass = UITableViewCell; frame = (0 22; 320 44); hidden = YES; autoresize = W; layer = <CALayer: 0x97f9740>>
$26 = 0x0a6a4a00 <DDSImageSubtitleCheckedTableViewCell: 0xa6a4a00; baseClass = UITableViewCell; frame = (0 66; 320 44); hidden = YES; autoresize = W; layer = <CALayer: 0xa6a4b50>>
$27 = 0x0a3ad250 <DDSImageSubtitleCheckedTableViewCell: 0xa3ad250; baseClass = UITableViewCell; frame = (0 110; 320 44); hidden = YES; autoresize = W; layer = <CALayer: 0xa3ad390>>
$28 = 0x0a3ae640 <DDSImageSubtitleCheckedTableViewCell: 0xa3ae640; baseClass = UITableViewCell; frame = (0 176; 320 44); hidden = YES; autoresize = W; layer = <CALayer: 0xa3ae780>>
$29 = 0x0972a370 <DDSImageSubtitleCheckedTableViewCell: 0x972a370; baseClass = UITableViewCell; frame = (0 220; 320 44); hidden = YES; autoresize = W; layer = <CALayer: 0x972a340>>

如果你只想要地址

0x097f9850
0x0a6a4a00
0x0a3ad250
0x0a3ae640
0x0972a370

【讨论】:

  • 这两个断点设置屏幕截图看似相同,但输出不同。他们应该在“调试器命令”字段中有不同的内容吗?
  • @pix 好眼力。感谢您发现错字,它应该是 'p cell' 而不是 'po cell' p 是原始打印,其中 po 是打印对象并调用 [cell description]。我已经破解了图像。再次感谢。
【解决方案2】:

它不会返回 nil,因为您已经注册了一个用于单元重用的 nib ([[self tableView] registerNib:nib forCellReuseIdentifier:@"MyCell"];)。

如果dequeueReusableCellWithIdentifier: 在 tableviews 重用队列中找不到单元格,它将从您指定的 nib 实例化一个新单元格。

【讨论】:

  • 也许吧,但他实际上在viewDidLoad 中注册了笔尖,并且注册的笔尖优先于原型单元。并且 nib 不能为 nil,否则他会覆盖单元格原型并且出队不会返回单元格。我猜在内部,原型单元格的存储方式与注册的笔尖相同。总结:对registerNib:forCellReuseIdentifier: 的实际调用导致出队返回一个单元格,但也可能有一个原型单元格。找出答案的唯一方法是删除registerNib:: 调用。无意冒犯,我已经完成了挑剔:-)
  • 虽然我很欣赏详尽的回复,但当我浏览原始代码示例时,我根本没有注意到他注册了 NIB(这很有趣,因为我清理了他的源代码)。我只是对他关于dequeue... 返回nil 的问题作出反应。正如我们所知,当您注册 NIB 以及使用单元原型时,都会发生这种情况。但是你说的很对,因为他在他的代码示例中注册了一个 NIB,这导致 dequeue... 永远不会返回 nil
【解决方案3】:

正如其他人所指出的,如果您注册了一个 nib 以重用 tableViewCell,则可以保证获得一个单元格实例。如果要为单元格设置一些值。您可以尝试像这样修改您的代码

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

        PHResultTableViewCell *cell = (PHResultTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"MyCell" 
                                                                                               forIndexPath:indexPath];];

        cell.packageHolidayItem = totalArray[indexPath.row];;
        [cell loadRow];

        return cell;
    }    

【讨论】:

  • 是的,我正在使用故事板
  • @TrineHaalsMadsen 请验证情节提要中给出的 cellIdentifier 是否正确。我已经更新了我的答案。
【解决方案4】:

我不相信它应该返回 nil。你为什么想要它?

方法dequeueReusableCellWithIdentifier返回一个即将显示的Cell,所以它不为null其实很好——这样你可以根据需要修改它。

【讨论】:

    猜你喜欢
    • 2014-09-27
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    • 2014-01-17
    • 2012-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多