[英]How get Realm result of objects in background queue, then use it on main thread
[英]Can we generate Realm results in background queue and use it on main thread
我最近开始使用 Realm,我不确定我的用例是否有效:
通常,当从数据库读取大量数据时,我想将其放入后台队列,以便异步获取数据,然后在主线程上使用它。
例如,我想根据城市获取多个结果:
private var results: [Results<SomeObject>?] = []
autoreleasepool {
DispatchQueue(label: "background").async {
[unowned self] in
do
{
let realm = try Realm()
for i in 1...City.count
{
self.results.append(realm.objects(SomeObject.self).filter("city=\(i)"))
}
}
catch
{
NSLog("Failed to open Realm instance on background qeueue")
}
}
}
稍后使用results
更新我的图表:
cell.setChartData(ChartDataFactory.createCombinedData(from: results[0]))
但是,如果我将此模型应用于 Realm,则会出现类似错误
由于未捕获的异常“RLMException”而终止应用程序,原因:“从不正确的线程访问的领域。
我知道我必须为每个线程使用领域,我可以通过在主线程上读取领域来做到这一点,但我不希望领域查询阻塞我的主线程。
有什么办法可以实现我的目标吗? 例如,在后台队列中读取领域并从另一个线程访问结果,同时保持自动刷新功能。
谢谢。
Realm 具有在后台线程上运行查询并使用Results.observe()将结果传送到主线程的内置功能。
如果您特别需要执行无法表示为 Realm 查询的昂贵过滤逻辑,您可以使用ThreadSafeReference在线程之间手动传递对象数组。
从 5.0 开始,您现在可以在后台线程上构造查询,并使用on:
参数来observe()
在主线程上接收通知:
DispatchQueue.global().async {
let realm = try! Realm()
let results = realm.objects(ObjectType.self).filter("property in %@", expensiveFunction(realm))
self.token = results.observe(on: .main) { change in
// do stuff with the results on the main thread
}
}
领域对象只能通过从中获取或创建它们的领域访问。 领域实例不能在线程(您知道)之间共享,并且从特定领域实例向另一个线程共享对象,隐式地具有与线程之间共享领域实例相同的效果。 这是由于对象和领域实例之间的紧密耦合。
正如此 GitHub 问题https://github.com/realm/realm-cocoa/issues/946中所述,推荐的做法是共享主键(如果您的领域对象覆盖 RealmObject (Objective-C) /对象(Swift))。
您正在尝试从不同的队列直接访问“结果”属性,这会崩溃。 您应该改为使用 ThreadSafeReference,如 Thomas 的回答所示。
在从 Realm 数据库获取之前,请确保为结果创建一个 ThreadSafeReference 并在后台队列上调用 realm.resolve() 。
我是这样解决的。 我看到了整体性能改进,但我找不到任何用于在后台线程上查询的实现示例。 可能有一个性能更好的解决方案。
self.results = self.realm.objects(Object.self).filter(predicate).sorted(by: sortProperties)
self.notificationToken = self.results.observe({ (notification) in
self.tableview.reloadData()
})
这是在 iPhone X 上的结果,数据库包含约 171k 项。 持续时间以秒为单位。
在用户界面上搜索:
UI thread blocked 0.730504035949707
使用上面的代码搜索:
UI thread blocked 0.28138411045074463
background search duration 0.5073530673980713
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.