更新无效:第 0 节中的项目数无效。

Invalid update: invalid number of items in section 0.

最近我收到以下错误:

Fatal Exception: NSInternalInconsistencyException Invalid update: invalid number of items in section 0. The number of items contained in an existing section after the update (13) must be equal to the number of items contained in that section before the update (12), plus or minus the number of items inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of items moved into or out of that section (0 moved in, 0 moved out).

错误出现在我的tvOS客户端中的以下代码中:

 let removedIndexPaths = removedIndexes.map({ IndexPath(row: [=10=], section: 0) })
 let addedIndexPaths = addedIndexes.map({ IndexPath(row: [=10=], section: 0) })
 let updatedIndexPaths = updatedIndexes.map({ IndexPath(row: [=10=], section: 0) })

  self.collectionView?.performBatchUpdates({
      self.collectionView?.deleteItems(at: removedIndexPaths)
      self.collectionView?.insertItems(at: addedIndexPaths)
      }, completion: { _ in
          guard let collectionView = self.collectionView else {
              return
          }

          for indexPath in updatedIndexPaths {
              if let myCell = collectionView.cellForItem(at: indexPath) as? MyCollectionViewCell {
                  let item = self.dataManager.items[indexPath.row]
                  myCell.updateUI(item)
               }
          }

          let collectionViewLayout = self.collectionViewLayoutForNumberOfItems(self.dataManager.items.count)
          if collectionViewLayout.itemSize != self.collectionFlowLayout.itemSize {
                collectionView.setCollectionViewLayout(collectionViewLayout, animated: false)
          }
  })

我在 collection 视图中只使用了一个部分:

override func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1
}

我查看了几个关于同一主题的帖子,但它们都没有解决我的问题,我猜测问题出在以下两行,但我不确定:

 self.collectionView?.deleteItems(at: removedIndexPaths)
 self.collectionView?.insertItems(at: addedIndexPaths)

请帮忙。

insertItems(at:) and deleteItems(at:) 的调用也必须伴随数据源的更改。

因此,在调用这些 API 之前,您需要更改数据源,即在调用 insertItems 之前向其中添加对象,在调用 deleteItems

之前从中删除对象

找到一篇关于 UICollectionView invalid number of items 崩溃问题的非常好的文章 - https://fangpenlin.com/posts/2016/04/29/uicollectionview-invalid-number-of-items-crash-issue/

由 collectionView(_:numberOfItemsInSection:) 编辑的项目计数 return 应该与闭包内的更新同步。有了这个想法,就很容易解决了,只需要添加一个属性作为item count,然后在performBatchUpdates闭包里面更新

func updateItems(updates: [ItemUpdate]) {
collectionView.performBatchUpdates({
  for update in updates {
      switch update {
      case .Add(let index):
          collectionView.insertItemsAtIndexPaths([NSIndexPath(forItem: index, inSection: 0)])
          itemCount += 1
      case .Delete(let index):
          collectionView.deleteItemsAtIndexPaths([NSIndexPath(forItem: index, inSection: 0)])
          itemCount -= 1
      }
    }
  }, completion: nil)
}

并且对于 collectionView(_:numberOfItemsInSection:),我们 returning items.count 而不是 return 由 performBatchUpdates 闭包手动维护的 属性。

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return itemCount
}