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

Posted

技术标签:

【中文标题】无效更新:第 0 节中的项目数无效。【英文标题】:Invalid update: invalid number of items in section 0. 【发布时间】:2017-09-10 12:45:01 【问题描述】:

最近报错:

致命异常:NSInternalInconsistencyException 更新后现有节中包含的项目数 (13) 必须 等于该部分中包含的项目数之前 update(12),加上或减去插入或删除的项目数 从该部分(0 插入,0 删除)加或减数字 移入或移出该部分的项目数(0 移入,0 移出)。

错误发生在我的 tvOS 客户端的以下代码中:

 let removedIndexPaths = removedIndexes.map( IndexPath(row: $0, section: 0) )
 let addedIndexPaths = addedIndexes.map( IndexPath(row: $0, section: 0) )
 let updatedIndexPaths = updatedIndexes.map( IndexPath(row: $0, 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)
          
  )

我只在我的收藏视图中使用了一个部分:

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

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

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

请帮忙。

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

【参考方案2】:

找到一篇非常不错的文章,关于 UICollectionView 无效的项目数崩溃问题 - https://fangpenlin.com/posts/2016/04/29/uicollectionview-invalid-number-of-items-crash-issue/

collectionView(_:numberOfItemsInSection:) 返回的项目计数应该与闭包内的更新同步。有了这个想法,很容易解决,只需添加一个属性作为项目计数并在 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:),我们返回的不是返回 items.count,而是由 performBatchUpdates 闭包手动维护的属性。

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

【讨论】:

以上是关于无效更新:第 0 节中的项目数无效。的主要内容,如果未能解决你的问题,请参考以下文章

NSInternalInconsistencyException 原因:'无效更新:第 0 节中的行数无效'

NSInternalInconsistencyException(无效更新:第 0 节中的行数无效)

tableView 编辑委托方法不起作用(无效更新:第 0 节中的行数无效)

无效更新:第 0 节中的无效行数以 NSException 类型的未捕获异常终止

无效更新:第 0 节中的无效行数。更新后现有节中包含的行数 (3)

iOS 8:从 NSFetchedResultsController 的委托中捕获异常,无效更新:第 0 节中的行数无效