ios – 在生产中使用Realm Collection更改通知

From the docs,我正在使用类似的东西来根据模型更改动态更新表视图:

let results = realm.objects(Message).filter("someQuery == 'something'").sorted("timeStamp", ascending: true)

// Observe Results Notifications
notificationToken = results.addNotificationBlock { [weak self] (changes: RealmCollectionChange) in
  guard let tableView = self?.tableView else { return }
  switch changes {
  case .Initial:
    // Results are now populated and can be accessed without blocking the UI
    tableView.reloadData()
    break
  case .Update(_, let deletions, let insertions, let modifications):
    // Query results have changed, so apply them to the UITableView
    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()
    break
  case .Error(let error):
    // An error occurred while opening the Realm file on the background worker thread
    fatalError("\(error)")
    break
  }
}

文档没有详细说明表的数据源委托如何获取此更改的数据,因此我认为使用自定义getter的属性会:

var rows: Results<Message> {
    let realm = try! Realm()
    return result = realm.objects(Message).filter("someQuery == 'something'").sorted("timeStamp", ascending: true)
}

这在实践中运作良好,但注释结果现在已填充,可以访问而不会阻止UI让我质疑这种方法.我的getter是否应返回一个空数组,直到.Initial通知在通知块中触发,以确保主线程永远不会被阻塞?

最佳答案 从文档的更改通知部分可能并不明显,但它实际上涵盖了
here in the docs.

结果对象是实时的,自动更新的对象.当他们的值在应用程序的其他地方(或后台线程)中更改时,他们将使用新值自动更新运行循环的下一次迭代(有警告.需要显式更新后台线程的结果).

更改通知的要点仅仅是告诉您已发生更改,并且下次访问结果时,新值将已存在.这样您就可以相应地更新UI.

因此,您的额外代码不是必需的.只需确保在触发更改通知块时,您在刷新UI时仍然引用相同的父结果对象,它应该只是工作™. 🙂

点赞