我有一个兴趣点列表。这些点是从 Realm 数据库加载的。每个点都应显示其到用户位置的距离。
每次我获得一个新位置时,我都会计算到所有点的距离。为了避免屏幕卡住,在主线程的表格中显示列表后,我在后台线程中进行数学计算。
func updatedLocation(currentLocation: CLLocation) {
let qualityOfServiceClass = QOS_CLASS_BACKGROUND
let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
dispatch_async(backgroundQueue, {
for point in self.points{
let stringDistance = self.distanceToPoint(currentLocation, destination: point.coordinate)
point.stringDistance = stringDistance
}
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView?.reloadData()
})
})
}
但是我收到此错误:
libc++abi.dylib: terminating with uncaught exception of type realm::IncorrectThreadException: Realm accessed from incorrect thread.
我知道我收到此错误是因为我正在后台线程中访问 Realm 对象,但是,它们已经加载到数组中,并且我从未对数据库进行新查询。 另外,我正在更新的变量没有保存到数据库中。
知道如何解决这个问题吗?我想避免在主线程中进行数学计算。
提前致谢
最佳答案
我假设您将 Realm Results
对象包装到 Array
中,如下所示:
let results = realm.objects(Point)
self.points = Array(results)
但是,这还不够。因为数组中的每个元素仍然与 Realm 绑定(bind),所以无法访问另一个线程。
推荐的方法是重新创建 Realm 并重新获取每个线程的结果。
dispatch_async(backgroundQueue, {
let realm = try! Realm()
let points = realm.objects(...)
try! realm.write {
for point in points{
let stringDistance = self.distanceToPoint(currentLocation, destination: point.coordinate)
point.stringDistance = stringDistance
}
}
dispatch_async(dispatch_get_main_queue(), { () -> Void in
...
})
})
Realm 对象具有实时更新功能。当提交更改到子线程上的 Realm 对象时,这些更改会立即反射(reflect)到其他线程中的对象。所以你不需要在主线程中重新获取查询。您应该做的只是重新加载表格 View 。
如果您想包装数组并将其直接传递给其他线程,则应按如下方式包装结果的所有元素:
let results = realm.objects(Point)
self.points = results.map { (point) -> Point in
return Point(value: point)
}
关于ios - 访问 Realms 对象列表时出错 : Realm accessed from incorrect thread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38892564/