tableView:dequeueReusableCellWithIdentifier问题与“全局”常量

请保存我的头发,或指出我的(明显的)错误。 我想在UITableViewCellStyleSubtitle的子类中使用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]; } 

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

我的猜测是,这个常量实际上并不是静态的,或者是有一个bug(8.0.2),或者是因为缺乏睡眠或者其他原因而完全缺失了某些东西。

还可以注意到,如果我不注册类,那么即使单元格标识符不同,也会出现编译器错误(预期),但不会出现错误(我猜测这是因为我可以为不同的单元格样式注册不同的类。

我错过了什么?

编辑

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

较短的问题

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

额外

一些更多的testing产生了一些不同的结果。 如果你注册一个cell重用标识符的类,然后在cellForRowAtIndexPath为ce​​ll指定一个不同的标识符,那么它就起作用了。 如果你给它与注册类相同的名称,那么它不会按预期工作。

回答

经过一些testing,@ MANIAK_dobrii的回答,一些清晰。

如果您想使用更新的单元出队方法dequeueReusableCellWithIdentifier:forIndexPath并且需要使用非默认的UITableViewCellStyle ,则需要dequeueReusableCellWithIdentifier:forIndexPath UITableViewCell并重写initWithStyle方法调用中的tableview样式。

如果你很乐意使用旧的方法,那么确保你没有注册一个类的重用标识符,否则将无法正常工作。

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

如果您为指定的标识符注册了一个类,并且必须创build一个新的单元格,则此方法通过调用其initWithStyle:reuseIdentifier:方法来初始化该单元格。 对于基于笔尖的单元格,此方法从提供的nib文件加载单元格对象。 如果现有的单元可用于重用,则此方法将调用单元的prepareForReuse方法。

这是否意味着,如果你注册一个类,甚至dequeueReusableCellWithIdentifier:将尝试创build单元格,如果它不是在重用队列中可用,并始终返回一个有效的单元格? 由于-dequeueReusableCellWithIdentifier:forIndexPath:可用,我只使用它。 所以,我的猜测是你的

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

永远不会被调用,并最终通过创build单元格

 [[registred_class alloc] initWithStyle:STANDARD_STYLE reuseIdentifier:registred_reuse_identifier]; 

同时,你已经说过,如果你没有注册类,会得到编译时错误,这很奇怪,你不应该得到任何错误。

所以,我的解决scheme将是或:
1.不要通过-registerClass:forCellReuseIdentifier:注册单元类-registerClass:forCellReuseIdentifier:并使用-dequeueReusableCellWithIdentifier:获取重用单元格或创build它们,就像现在这样做。 再次,使用oldschool的方法,你不注册任何东西,只是出现,如果有,创build,如果没有。

 // 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 // ie 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.创buildnib,把一个UITableViewCell放在那里,使它的风格是UITableViewCellStyleSubtitle并且注册该nib作为重用标识符,而不是registerNib:forCellReuseIdentifier:的类registerNib:forCellReuseIdentifier:

另外,确保所有的标题/颜色/透明胶片都是正确的,这样您就不会将空string或零设置为单元格上的标签。