无法对具有标识符标题的单元格进行双端队列处理

Unable to deque cell with identifier title

当我按下打开表格视图的按钮时出现以下错误:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier title - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'

这是表视图的视图控制器中的代码以及导致问题的方法:

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

NSString *CellIdentifier = [menuItems objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

return cell;
}

我研究了错误并尝试删除 forIndexPath:indexPath 所以代码看起来像:

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

NSString *CellIdentifier = [menuItems objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

return cell;
}

现在这导致了一个新的错误:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:

现在我做了一些日志记录,发现 cell == nil 是真的,所以我添加了一个检查,正如之前一些问题所建议的:

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

NSString *CellIdentifier = [menuItems objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil){
     cell = [[UITableViewCell alloc] init]
}

return cell;
}

现在这消除了所有错误,但现在当我打开表格视图时,当我想要我在情节提要中创建的单元格时,单元格是空的。

我该如何解决这个问题?

视图控制器在情节提要中的样子如下:

如果您在情节提要中创建原型单元格,则需要将它们的 "Identifier" 字段设置为您的 "CellIdentifier" 字符串。您可以通过选择单元格并在属性检查器中查看来执行此操作。

如果您要为您的 UITableViewCell 创建一个单独的 .xib 文件,您需要在某处的代码中对您的 UITableView 调用此方法:

registerNib:forCellReuseIdentifier:

如果您在代码中完成所有操作并且只使用知道如何自行布局的 UITableViewCell 子类,那么您需要在 UITableView 上调用此方法:

registerClass:forCellReuseIdentifier:

这里有一个link参考docs

您可以在 UITable 上调用两种单元格回收方法 查看,

-(UITableViewCell *) dequeueReusableCellWithIdentifier:forIndexPath:
-(UITableViewCell *)dequeueReusableCellWithIdentifier:

这有点令人困惑,但它们的使用方式却大不相同。接受第二个参数(NSIndexPath 类型)的参数取决于您是否首先使用 tableView 注册了一个 class 或 xib 文件,以便 tableView 可以创建一个当没有方便回收的电池时,为您提供临时电池。第一种方法将始终 return 一个单元格,因此您可以像编写 cellForRowAtIndexPath: 一样编写代码。

第二种方法(只接受一个参数,当没有方便回收的单元时,(NSString *)cellIdentifier 可以并且将 return nil。所以当你使用这个方法时,你应该测试结果对于 nil 并在这种情况下创建一个单元格。 例如

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

  static NSString *cellId = @"cellID";

  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];

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

 //etc etc decorate your cell...

  return cell;
}

为了利用您的单元原型,您需要为每个 row/section 注册一个 class 或 xib,以便 table 知道要创建哪个单元。只有在创建了足够多的单元格来填满屏幕并且您开始滚动时,回收的东西才真正起作用。祝你好运