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

时间:2016-05-21 09:09:52

标签: ios swift realm

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)
}

这在实践中运作良好,但评论Results are now populated and can be accessed without blocking the UI让我质疑这种方法。我的getter是否应返回一个空数组,直到在通知块中触发.Initial通知,以确保主线程永远不被阻止?

1 个答案:

答案 0 :(得分:2)

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

Results个对象是实时的自动更新对象。当他们的值在应用程序的其他地方(或后台线程)中更改时,它们将在运行循环的下一次迭代中使用新值自动更新(有一些警告。后台线程上的Results需要明确更新)。

更改通知的目的只是告诉您发生了更改,下次访问results时,新值已经存在。这样您就可以相应地更新UI。

因此,您的额外代码不是必需的。只需确保在触发更改通知块时,您在刷新UI时仍然引用相同的父results对象,它应该 just work™。 :)