我正在使用NSFetchedResultsController
和UICollectionView
创建媒体库。
由于使用NSFetchedResultsControllerDelegate
在collectionView上应用更新存在很多问题,因此我正在使用以下实现:
public func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
if type == .insert {
blockOperations.append(
BlockOperation(block: { [weak self] in
self?.collectionView.insertSections(IndexSet(integer: sectionIndex))
})
)
} else if type == .update {
blockOperations.append(
BlockOperation(block: { [weak self] in
self?.collectionView.reloadSections(NSIndexSet(index: sectionIndex) as IndexSet)
})
)
} else if type == .delete {
blockOperations.append(
BlockOperation(block: { [weak self] in
self?.collectionView.deleteSections(NSIndexSet(index: sectionIndex) as IndexSet)
})
)
}
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
if type == .insert {
if self.collectionView.numberOfSections > 0 {
guard let newIndexPathSection = newIndexPath?.section else {
return
}
if self.collectionView.numberOfItems(inSection: newIndexPathSection) == 0 {
self.shouldReloadCollectionView = true
} else {
guard let newIndexPath = newIndexPath else {
return
}
self.blockOperations.append(
BlockOperation(block: { [weak self] in
self?.collectionView.insertItems(at: [newIndexPath])
})
)
}
} else {
self.shouldReloadCollectionView = true
}
} else if type == .update {
guard let indexPath = indexPath else {
return
}
self.blockOperations.append(
BlockOperation(block: { [weak self] in
self?.collectionView.reloadItems(at: [indexPath])
})
)
} else if type == .move {
guard let indexPath = indexPath, let newIndexPath = newIndexPath else {
return
}
self.blockOperations.append(
BlockOperation(block: { [weak self] in
self?.collectionView.moveItem(at: indexPath, to: newIndexPath)
})
)
} else if type == .delete {
guard let indexPath = indexPath else {
return
}
if self.collectionView.numberOfItems(inSection: indexPath.section) == 1 {
self.shouldReloadCollectionView = true
} else {
self.blockOperations.append(
BlockOperation(block: { [weak self] in
self?.collectionView.deleteItems(at: [indexPath])
})
)
}
}
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
if shouldReloadCollectionView {
self.collectionView.reloadData()
} else {
self.collectionView.performBatchUpdates({
for operation: BlockOperation in self.blockOperations {
operation.start()
}
}, completion: { _ in
self.blockOperations.removeAll(keepingCapacity: false)
})
}
}
当保存大量媒体时,很显然索引有很多更改。因此会引发错误:
***由于未捕获的异常“ NSInternalInconsistencyException”而终止应用程序,原因:“请求的数量 集合中只有1个部分时,第1部分中的项目 查看”
我发现这是在致电时发生的:
collectionView.numberOfItems(inSection: newIndexPathSection)
调用controllerDidChangeAnObject
时。
如何解决此错误? 谢谢