addNotificationBlock {RealmCollectionChange}在UITableView中崩溃

时间:2016-06-24 16:34:52

标签: ios swift uitableview realm

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

  1. ***由于未捕获的异常终止应用' RLMException',原因:'只能在runloops中添加通知块。'
  2. 即使我在ViewController类中提取主线程中的所有数据,也会发生此崩溃。

    1. ***断言失败 - [UITableView _endCellAnimationsWithContext:],/ BuildRoot / Library / Cache / com.apple.xbs / Source / UIKit / UIKit-3512.30.14 / UITableView.m:1720 ****由于未捕获的异常终止应用程序' NSInternalInconsistencyException',原因:'无效更新:第0部分中的行数无效。更新后现有部分中包含的行数(27) )必须等于更新前的该部分中包含的行数(17),加上或减去从该部分插入或删除的行数(9插入,0删除)和加或减移入的行数或超出该部分(0移入,0移出)。'
    2. 此更新仅在我更换

      后才开始发生
      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
        }
      }
      

1 个答案:

答案 0 :(得分:2)

听起来你可能会在这里稍微复杂一点。

领域Results对象是实时和自动更新的。在主运行循环的下一次迭代中,对其底层对象所做的意义更改会自动更新,因此无需对它们执行手动重新获取。在您的代码中,您在生成令牌后,在self.exhibits更改通知中重新分配.Initial,这可能会导致您的一些问题。如果删除该行,它应该继续工作。

我建议您浏览一下代码,并确保self.exhibits仅被分配一次,并且更改通知方法仅适用于该代码。

如果没有解决它,请告诉我。