ios - addNotificationBlock { RealmCollectionChange } 在 UITableView 中崩溃

标签 ios swift uitableview realm

我正在使用 Realm for Swift 并将数据加载到 UITableView 中。当我进入屏幕时,大约有 200 个数据对象正在逐渐下载,因此在显示 tableview 后,我的测试中发生了向 UITableView 的大量插入。我正在尽可能接近地使用 Realm 示例来 addNotificationBlock 和 RealmCollectionChange,在此过程中偶尔会发生两次单独的崩溃。

  1. *** 由于未捕获的异常“RLMException”而终止应用程序,原因:“只能从运行循环内添加通知 block 。”

即使我特意从 ViewController 类中的主线程中提取所有数据,也会发生此崩溃。

  • *** -[UITableView _endCellAnimationsWithContext:] 中的断言失败,/BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3512.30.14/UITableView.m:1720 **** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无效更新:第 0 节中的行数无效。更新后现有节中包含的行数 (27) 必须等于更新之前该部分中包含的行数 (17),加上或减去从该部分插入或删除的行数(插入 9 行,删除 0 行)以及移入或移出该部分的行数(移动 0 行)移入,0 移出)。'
  • 此崩溃仅在我更换后才开始发生

    tableView.reloadData()
    

    tableView.beginUpdates()
            tableView.insertRowsAtIndexPaths(insertions.map { NSIndexPath(forRow: $0, inSection: 0) },
              withRowAnimation: .Automatic)
            tableView.deleteRowsAtIndexPaths(deletions.map { NSIndexPath(forRow: $0, inSection: 0) },
              withRowAnimation: .Automatic)
            tableView.reloadRowsAtIndexPaths(modifications.map { NSIndexPath(forRow: $0, inSection: 0) },
              withRowAnimation: .Automatic)
            tableView.endUpdates()
    

    在我的 addNotificationBlock 的 .Update() 部分

    我是否遗漏了 Realm 中的某些内容导致了这种情况?我怀疑这是因为我没有完全理解这个库的内部机制。

    这是我的引用代码:

    self.exhibits = DataManager.getAllExhibitsSorted("id")
    token = self.exhibits?.addNotificationBlock { (changes: RealmCollectionChange) in
      switch changes {
      case .Initial(_):
    
        self.exhibits = DataManager.getAllExhibitsSorted("id")
        self.exhibitListTableView.reloadData()
        break
      case .Update(_, let deletions, let insertions, let modifications):
    
        // Query results have changed, so apply them to the UITableView
        self.exhibitListTableView.beginUpdates()
        self.exhibitListTableView.insertRowsAtIndexPaths(insertions.map { NSIndexPath(forRow: $0, inSection: 0) },
          withRowAnimation: .Automatic)
        self.exhibitListTableView.deleteRowsAtIndexPaths(deletions.map { NSIndexPath(forRow: $0, inSection: 0) },
          withRowAnimation: .Automatic)
        self.exhibitListTableView.reloadRowsAtIndexPaths(modifications.map { NSIndexPath(forRow: $0, inSection: 0) },
          withRowAnimation: .Automatic)
        self.exhibitListTableView.endUpdates()
    
        break
      case .Error:
        NSLog("Error in notificationBlock")
        break
      }
    }
    

    最佳答案

    听起来你可能把事情变得过于复杂了。

    Realm Results 对象是实时且自动更新的。这意味着对其基础对象所做的更改会在主运行循环的下一次迭代中自动更新,因此无需对它们执行手动重新获取。在您的代码中,在生成 token 后,您将在 .Initial 更改通知中重新分配 self.exhibits,这可能会导致您出现一些问题这里。如果您删除该行,它应该会继续工作。

    我建议检查您的代码,并确保 self.exhibits 仅分配一次,并且更改通知方法仅应用于该方法。

    如果这不能解决问题,请告诉我。

    关于ios - addNotificationBlock { RealmCollectionChange } 在 UITableView 中崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38018213/

    相关文章:

    ios - 在 iPhone 上阅读资源文本文件

    ios - 更改 collectionView 中的图像以匹配数组中保存的购买项目

    objective-c - cocos2D<不起作用

    arrays - swift 3 : binary operator cannot be applied to operands of type int and 'Int?'

    ios - nsuserdefault 不保存数组 - Swift

    ios - 如何子类化自定义 UITableViewCell?

    ios - 使用 NSPrivateQueueConcurrencyType 的具体/完整示例?

    ios - 插入内联日期选择器 View 单元格 - swift

    ios - Swift:将回调传递给结构实例

    macos - IBInspectable 不呈现 NSView 层