ios - dequeueReusableCellWithIdentifier 索引越界

标签 ios uitableview swift

=> Demo Project @ GitHub <=

我有一个 UITableViewController,其中有一个 TableView,其中我有一个 Cell,其中有另一个 TableView

当内部 TableView 为 indexPath (1,0) 尝试 dequeueReusableCellWithIdentifier 时,应用程序崩溃了

Terminating app due to uncaught exception 'NSRangeException', 
reason: '*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'

尽管内部 TableView 显然有 3 个部分。堆栈跟踪是:

-[__NSArrayI objectAtIndex:] + 190
-[UITableViewDataSource tableView:indentationLevelForRowAtIndexPath:] + 61
-[UITableView _configureCellForDisplay:forIndexPath:]_block_invoke + 1711
+[UIView(Animation) performWithoutAnimation:] + 65
-[UITableView _configureCellForDisplay:forIndexPath:] + 312
-[UITableView dequeueReusableCellWithIdentifier:forIndexPath:] + 271

因为跟踪,我尝试实现

override func tableView(tableView: UITableView, 
              indentationLevelForRowAtIndexPath indexPath: NSIndexPath) -> Int {
  return 0
}

但随后应用程序崩溃了

-[UITableViewDataSource tableView:viewForFooterInSection:]

具有相同的索引 1 超出范围 [0 .. 0]...

恕我直言,实现相对无关紧要,但确实如此

override func tableView(tableView: UITableView, 
              cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
  if tableView.tag == 0 {
    return super.tableView(tableView, cellForRowAtIndexPath: indexPath)
  }
  if let cell = tableView.dequeueReusableCellWithIdentifier("cell") as? UITableViewCell {
    return cell
  }
  return UITableViewCell() // Shouldn't happen.
}

我对最后一行并不感到非常自豪 :) 但是您还可以做些什么来取悦编译器?我从来没有达到那条线。崩溃显然发生在 tag 为 1 的内部 TableView 中。

最佳答案

问题是对

的调用
super.tableView(tableView, cellForRowAtIndexPath: indexPath)

但是 MasterViewControllerUITableViewController 的子类,所以你调用基类 UITableViewControllercellForRowAtIndexPath >。我想理解您的代码的意图(“嘿,我希望子级 cellForRowAtIndexPath 在适当的情况下调用父级”),但是您将类层次结构与 View 层次结构混为一谈。这不是实现您想要的方法。

相反,您可以执行以下操作:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    if tableView.tag == 0 {
        return tableView.dequeueReusableCellWithIdentifier("ParentCell", forIndexPath: indexPath) as! UITableViewCell
    }

    return tableView.dequeueReusableCellWithIdentifier("ChildCell", forIndexPath: indexPath) as! UITableViewCell
}

这为 0tag 实例化了一种单元格类型,为 1 实例化了另一种单元格类型。请注意,我已经更改了 Storyboard以使两个 TableView 都使用动态原型(prototype),并且我已经更改了两个 TableView 的标识符,如上所示。

坦率地说,我认为让一个对象尝试充当两种不同类型的 TableView 的委托(delegate)是错误的。如果你真的有一个 View Controller 和两个 TableView ,我认为为每个 TableView 实现一个自定义委托(delegate)对象,根据需要实例化它们,设置 delegatedataSource 适当的 TableView 。这样一来,您就可以避免在所有委托(delegate)方法中乱加“如果表 0 执行 x 否则执行 y”逻辑。

但是,更广泛地说,我建议不要在 TableView 中使用 TableView 。

关于ios - dequeueReusableCellWithIdentifier 索引越界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30545330/

相关文章:

swift - 在swift中添加制表符

iOS慢速图像像素迭代

ios - UITableViewCell 删除不使用正确的 UITableViewRowAnimation

ios - 创建具有默认行为的更可重用的 UITableView 子类

ios - 如何在用户滑动并看到 'Delete' 按钮时更新 UITableView 单元格?

ios - UIDocumentInteractionController PresentOpenInMenuFromRect

ios - 预期标识符或 "("Objective C

ios - 应用程序在 AppDelegate 中崩溃,无法通过启动屏幕

ios - 速记比较最终太长而无法理解

swift - 如何在点击手势上为 UIImageView 制作动画?