访问 Realms 对象列表时出错:从不正确的线程访问的领域
Error acessing list of Realm's objects: Realm accessed from incorrect thread
我有兴趣点列表。这些点是从 Realm 数据库 加载的。每个点都应显示其到 用户位置 .
的距离
每次我得到一个新位置,我都会计算到所有点的距离。为了避免屏幕冻结,我在主线程的 table 中显示列表后,在后台线程中进行数学计算。
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.
我知道我收到此错误是因为我正在后台线程中访问领域对象,但是,它们已经加载到数组中,我从未对数据库进行新查询。
另外,我正在更新的 var 没有保存到数据库中。
知道如何解决这个问题吗?我想避免在主线程中进行数学运算。
提前致谢
我假设您将 Realm Results
对象包装到 Array
中,如下所示:
let results = realm.objects(Point)
self.points = Array(results)
然而,这还不够。因为数组中的每个元素仍然与 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 对象时,这些更改会立即反映到其他线程中的对象。所以你不需要在主线程中重新获取查询。您应该做的只是重新加载 table 视图。
如果您想包装数组并将其直接传递给其他线程,您应该按如下方式包装结果的所有元素:
let results = realm.objects(Point)
self.points = results.map { (point) -> Point in
return Point(value: point)
}
我有兴趣点列表。这些点是从 Realm 数据库 加载的。每个点都应显示其到 用户位置 .
的距离每次我得到一个新位置,我都会计算到所有点的距离。为了避免屏幕冻结,我在主线程的 table 中显示列表后,在后台线程中进行数学计算。
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.
我知道我收到此错误是因为我正在后台线程中访问领域对象,但是,它们已经加载到数组中,我从未对数据库进行新查询。 另外,我正在更新的 var 没有保存到数据库中。
知道如何解决这个问题吗?我想避免在主线程中进行数学运算。
提前致谢
我假设您将 Realm Results
对象包装到 Array
中,如下所示:
let results = realm.objects(Point)
self.points = Array(results)
然而,这还不够。因为数组中的每个元素仍然与 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 对象时,这些更改会立即反映到其他线程中的对象。所以你不需要在主线程中重新获取查询。您应该做的只是重新加载 table 视图。
如果您想包装数组并将其直接传递给其他线程,您应该按如下方式包装结果的所有元素:
let results = realm.objects(Point)
self.points = results.map { (point) -> Point in
return Point(value: point)
}