我正在我的应用程序上构建一个屏幕,其中的配置文件将显示在 Collection View 中。正在从 Firebase 检索我的数据,这是我第一次使用 Firebase DatabaseUI。
我正在构建一个查询,然后创建一个 FUICollectionViewDataSource
,使我的单元格出列,然后将该数据源插入到 collectionView 中。
只要我在在线用户和离线用户之间切换(检查查询中子键的值),数据源的功能就可以正常工作,但是当我将查询从男性更改为女性时,或者女人对男人,(一个新的查询本身)我遇到了 NSInternalInconsistenencyException
。
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of items in section 0. The number of items contained in an existing section after the update (1) must be equal to the number of items contained in that section before the update (1), plus or minus the number of items inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of items moved into or out of that section (0 moved in, 0 moved out).'
*** First throw call stack: (0x18672d1b8 0x18516455c 0x18672d08c 0x1871e502c 0x18cedc14c 0x18c7b1d4c 0x10020f594 0x1002102c8 0x1001eb3e0 0x101609258 0x101609218 0x10160e280 0x1866da810 0x1866d83fc 0x1866062b8 0x1880ba198 0x18c64d7fc 0x18c648534 0x1000c4200 0x1855e95b8) libc++abi.dylib: terminating with uncaught exception of type NSException
当我构建 Collection View 时,我习惯于只运行这样的命令:
collectionView.dataSource = collectionViewDataSource
self.collectionView.reloadData()
但现在上面的调用不起作用,而且我没有使用 UICollectionViewDataSource
协议(protocol)函数,我不确定如何创建、运行和显示新的查询,这些查询总是每个部分有不同数量的项目。
在处理新查询之前我必须运行哪些函数才能不处理这些类型的崩溃?
我试过从 collectionView 的 indexPathsForVisibleItems
中删除所有单元格,然后重新加载数据...我在 collectionView.reloadData()
地方,仍然崩溃。不是所有时候,但应用程序迟早会崩溃。
如何在 collectionView 上开始一个全新的查询而不必处理 NSInternalInconsistencyExceptions
?
谢谢大家。我喜欢 Firebase 并且很想弄清楚这个问题!
-雷兹
当 VC 加载时,getUserData()
函数被调用。
当查询更改时,resetQuery()
函数从发布的通知中运行。
extension BrowseVC {
func getUserData() {
let isOnline = (segmentedControl.selectedSegmentIndex == 0) ? true : false
generateQuery(isOnline: isOnline)
populateDataSource()
}
func resetQuery() {
removeOldData()
getUserData()
}
func removeOldData() {
let indexPaths = collectionView.indexPathsForVisibleItems
collectionView.deleteItems(at: indexPaths)
// collectionView.reloadData()
}
func generateQuery(isOnline: Bool) {
if let selectedShowMe = UserDefaults.sharedInstance.string(forKey: Constants.ProfileKeys.ShowMe) {
let forMen = (selectedShowMe == Constants.ProfileValues.Men) ? true : false
query = FirebaseDB.sharedInstance.buildQuery(forMen: forMen, isOnline: isOnline)
} else {
query = FirebaseDB.sharedInstance.buildQuery(forMen: false, isOnline: isOnline)
}
}
func populateDataSource() {
if let query = query {
collectionViewDataSource = FUICollectionViewDataSource(query: query, view: collectionView, populateCell: { (view, indexPath, snapshot) -> ProfileCVCell in
if let cell = view.dequeueReusableCell(withReuseIdentifier: Constants.CollectionViewCellIdentifiers.ProfileCVCell, for: indexPath) as? ProfileCVCell {
if let userDictionary = snapshot.value as? [String: AnyObject] {
if let user = User(uid: snapshot.key, userDictionary: userDictionary) {
cell.populate(withUser: user)
}
}
return cell
}
return ProfileCVCell()
})
collectionView.dataSource = collectionViewDataSource
collectionView.reloadData()
// collectionView.performBatchUpdates({
// self.collectionView.dataSource = self.collectionViewDataSource
// }, completion: nil)
// collectionView.reloadData()
}
}
}
最佳答案
您遇到这种情况的原因是 FirebaseUI 数据库数据源承担了将更新推送到 Collection View 本身的责任。通过这种方式,您可以免费获得动画更新,而且永远不必调用 reloadData。
当您将旧数据源换成新数据源时,您需要将数据源的 Collection View 设置为nil
,这样它就停止将事件推送到 Collection View 。
关于ios - 如何处理 Swift 中 Firebase 数据库中的 'Assertion Failure' Collectionview 崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41887157/