【问题标题】:Reaching Realm Results object from different thread gives crash从不同的线程到达领域结果对象会导致崩溃
【发布时间】:2021-04-30 15:30:53
【问题描述】:

我的 viewModel 中有一个 Results 对象,定义和初始化如下

private var followings: Results<Following>!
// This runs in main thread
self.followers = try RealmHelper.getObjects(t: Follower.self)

在另一个函数中(在 self.followers 初始化并完成之后)我尝试在不同的线程中获取此以下对象,但出现以下崩溃。

由于未捕获的异常“RLMException”而终止应用程序,原因:“从错误线程访问的领域。”

DispatchQueue.global(qos: .userInitiated).async { 
  let currentFollowersIds = self.followers.filter("friendShip.isFollowingYou == true")
}

P.S:如果我用realm.objects(T.self) 得到我的对象 它不会崩溃。

P.S 2:我发现过滤会导致崩溃。如果我删除过滤,它可以工作,但我需要过滤。我尝试使用Array(followers).filter 将其分配给非实时数组,但也不起作用。

【问题讨论】:

  • 变量和对象令人困惑。有一个结果Following,然后是一个Follower 对象,然后是一个var followings,然后是另一个变量self.followers。然后是RealmHelper 对象- 那是单例吗?如果是这样,它将始终在同一个线程上,因此不清楚为什么涉及其他线程。 DispatchQueue 在查询中完全不需要,它应该只与写入一起使用,这样它们就不会占用 UI。您能否更新代码,以便我们知道什么是什么并澄清所询问的内容以及为什么要使用多个线程?

标签: ios swift realm


【解决方案1】:

Realm objects can only be used from the same thread that they were fetched.

因此,您有 2 个主要选项,如果您要使用任何数据来填充 UI,则必须在主线程中获取对象。

另一种选择是创建一个新的 Realm 实例并在主线程中再次获取结果,创建一个 Realm 应该是非常轻量级的。

您也可以在线程之间传递对象,但这更复杂。

【讨论】:

  • 这是一个很好的答案stackoverflow.com/a/46141584/4855680
  • 虽然这里有很好的信息,但它是旧信息。您可以轻松地将带有 ThreadsafeReference 的对象传递给对象,最酷的是 frozen 对象,它允许传递完整的集合,并在需要时解冻它们(随 10.5.2 发布)。话虽这么说,问题中的代码中没有任何内容表明问题出在哪里,因此问题更加清晰可能会导致更新/更好的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多