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时仍然引用相同的父结果对象,它应该只是工作™. 🙂