ios - 如何处理 Swift 中 Firebase 数据库中的 'Assertion Failure' Collectionview 崩溃?

标签 ios swift uicollectionview firebase-realtime-database firebaseui

我正在我的应用程序上构建一个屏幕,其中的配置文件将显示在 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/

相关文章:

ios - 从 Unix 时间戳日期 ios 数组在 Uitableview 中创建动态部分?

ios - 如何在 iOS 中使用 Twitter Kit/Fabric 从登录用户获取用户个人资料图像

ios 对用户的解析框架查询

arrays - 快速从元组数组中提取元组的元素

swift - 无法推断通用参数 'T' 的参数

ios - 如何使用单独的 Storyboard以编程方式正确设置 UITabBarController

ios - 如何为闭包分配内存及其存储机制是什么?

AppStore 中的 iOS 应用程序与 Xcode 中的工作方式不同

objective-c - 如何在 UICollection 补充 View 中使用 UIButton?

ios - 来自调试器 : Terminated due to memory issue While scrolling in UITableView/UICollectionView with gif images Kingfisher Library 的消息