[英]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.