我最近开始使用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")
}
}
}
Run Code Online (Sandbox Code Playgroud)
稍后用于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
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1963 次 |
| 最近记录: |