ios - 访问 Realms 对象列表时出错 : Realm accessed from incorrect thread

标签 ios swift multithreading ios9 realm

我有一个兴趣点列表。这些点是从 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/

相关文章:

multithreading - Python : multithreaded learning neural networks using PyBrain and Multiprocessing

php - pthreads等待线程功能在继续之前完成

iphone - asihttprequest的post和get请求有什么区别?

ios - 将图钉放在当前位置

ios - 像 Android GridLayout 中的单元格周围的边距

swift - swift 中的 UITextview 编辑模式

ios - 当前位置的注释图钉未出现

swift - 我如何使用 Swift 3 scheduleRepeating?

ios - 使用未解析的标识符 FBSDKAppEventNamePurchased

c# - 编写我自己的 IScheduler 来管理线程,最好的方法是什么?