tableView:dequeueReusableCellWithIdentifier与“全局”常量一起出现问题

时间:2014-10-20 10:03:53

标签: ios objective-c xcode uitableview

请保存我的头发或指出我的(明显的)错误。我试图在子类UITableViewController中使用UITableViewCellStyleSubtitle的UITableViewStyle。

我在实现中定义了一个静态常量:

static NSString * const kAHCellIdentifier;

viewDidLoad中我注册了一个tableView类:

[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:kAHCellIdentifier];

然后在tableView:cellForRowAtIndexPath中,我按如下方式初始化单元格:

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

运行应用程序(设备或SIM卡)时,单元格会加载,但detailTextLabel不会显示,但如果我这样初始化,它可以正常工作*

我的猜测是,常量实际上并不是静态的,或者存在一个错误(8.0.2),或者由于缺乏睡眠或其他原因,我完全缺少某些东西。

还可以注意到,如果我没有注册该类,则存在编译器错误(预期)但即使单元标识符不同也没有错误(我猜这是因为我可以注册不同的类针对不同的细胞样式。

我错过了什么?

修改

使用[tableView dequeueReusableCellWithIdentifier:kAHCellIdentifier forIndexPath:indexPath];也没有效果。

更短的问题

为什么dequeueReusableCellWithIdentifier返回nil,因此如果我在cell == nil方法调用中使用静态NSString,则使用cellForRowAtIndexPath块中的UITableViewCellStyle启动单元格,而不是,如果我使用上面定义的类级全局常量。

其他

更多测试产生了一些不同的结果。如果为单元重用标识符注册一个类,然后在cellForRowAtIndexPath中为单元格提供不同的标识符,那么它就可以工作。如果你给它与注册类同名,那么它就不会按预期工作。

答案

经过一些测试,@ MANIAK_dobrii的回答,一些清晰度。

如果您想使用较新的单元格出列方法dequeueReusableCellWithIdentifier:forIndexPath并且需要使用默认值以外的UITableViewCellStyle,则需要继承UITableViewCell并覆盖tableview样式在initWithStyle方法调用中。

如果您愿意使用旧方法,请确保您没有为重用标识符注册类别,否则它将无效。

1 个答案:

答案 0 :(得分:3)

这很有意思,因为我刚刚在dequeueReusableCellWithIdentifier:的文档中找到了一个新段落,我上次看到那里时没有看到:

  

如果您为指定的标识符和新单元格注册了一个类   必须创建,此方法通过调用它来初始化单元格   initWithStyle:reuseIdentifier:方法。对于基于笔尖的细胞,这个   方法从提供的nib文件加载单元格对象。如果   现有的单元可以重用,这种方法称为单元   而不是prepareForReuse方法。

这是否意味着如果您注册一个类,即使dequeueReusableCellWithIdentifier:会在重用队列中不可用并且总是返回一个有效的单元格,也会尝试创建单元格?由于-dequeueReusableCellWithIdentifier:forIndexPath:可用,我只使用它。所以,我的猜测是你的

if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}

永远不会被调用,你最终会得到通过

创建的单元格
[[registred_class alloc] initWithStyle:STANDARD_STYLE reuseIdentifier:registred_reuse_identifier];

与此同时,您已经声明,如果您没有注册课程,则会出现编译时错误,这很奇怪,您不应该

所以,我的解决方案是:或 1.不要通过-registerClass:forCellReuseIdentifier:注册细胞分类,并使用-dequeueReusableCellWithIdentifier:来获取重复使用的细胞,或者在您现在正在进行时创建它们。再次,使用oldschool方法,你不会注册任何东西,如果有的话就会出队,如果没有则会创建。

// I've put it here just for a clarification that that's doesn't matter for the case
static NSString *const cellID = @"CellID";
// Just this, do not register anything, cell should get the same id as you ask
// i.e. you should init cell with the same id you then try to dequeue
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
    if(!cell)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID];
    }

    cell.textLabel.text = @"Title";
    cell.detailTextLabel.text = @"subtitle";

    return cell;
}

或:
2.创建nib,在其中放置一个UITableViewCell,使其样式为UITableViewCellStyleSubtitle,并将该nib注册为重用标识符,而不是registerNib:forCellReuseIdentifier:的类。

此外,请确保将所有标题/颜色/透明度设置为正确,这样您就不必将空字符串或nil设置为单元格上的标签。