在从UITableView中删除项目之后,索引超出范围

请帮我看看我的错误是什么 我有一个表视图,数据源是一个名为items的数组。 从items数组中删除一个项目后,调用cellForRowAt方法,参数indexPath.row与items.count相等。 这只会发生,当行数足够一个项目不在表视图的视图。 发生时会导致严重的错误(索引超出范围)。 在这种情况下使用黑客攻击,并且IndexPath.row的值会减less。

请看下面的图片:

在这里输入图像说明

以下代码为cellForRowAt:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath) as! ItemCell var i = indexPath.row if i >= items.count { i = items.count - 1 } //XXX: hack! Sometimes called with indexPath.row is equal with items.count :( cell.set(items[i]) return cell } 

以下代码为删除:

  func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { if (editingStyle == UITableViewCellEditingStyle.delete) { items.remove(at: indexPath.row) tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.fade) } } 

我认为是不相关的,但我使用iOS 11.0

UPDATE

我试过了,下面这个非常简单的代码也受到影响:

  class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { var items = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"] override func viewDidLoad() { super.viewDidLoad() } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return items.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath) cell.textLabel?.text = "\(items[indexPath.row])" return cell } func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { if (editingStyle == UITableViewCellEditingStyle.delete) { items.remove(at: indexPath.row) tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.fade) } } } 

如何重现:

  1. 向下滚动到Y是屏幕上的最后一个项目

在这里输入图像说明

  1. 尝试删除Y滑动到左侧

在这里输入图像说明

  1. 并获得以下错误

在这里输入图像说明

在这里输入图像说明

你的删除代码看起来很好,但是你不应该在你的cellForRowAt做你正在做的事情。 这样做,而不是:

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath) as! ItemCell cell.set(items[indexPath.row]) return cell } 

而你的numberOfRowsInSection应该是这样的:

 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return items.count } 

更新:
我们刚刚确认这是一个与Xcode 9 beta和iOS 11相关的bug。在Xcode 8.x上运行良好。 OP会就此向苹果提交一个bug 。