【问题标题】:Realm accessed from incorrect thread. iOS Best Practice从不正确的线程访问的领域。 iOS 最佳实践
【发布时间】:2019-03-05 02:47:15
【问题描述】:

很久以前我曾经和Realm一起工作,但这是第一次面对这种崩溃

*** Terminating app due to uncaught exception 'RLMException', reason: 'Realm accessed from incorrect thread.'

经过一番搜索,我找到了有关每次您想在另一个队列中使用时创建一个新实例的解决方案。

 backgroundQueue.async {
    print("Dispatched to background queue")
    let realm = try! Realm()
     ....

似乎每次都在后台队列中创建新实例效率不高,所以我必须调整我的代码。 有什么办法可以解决吗?

尴尬的是我确保创建实例和调用它都发生在主线程上!!!

【问题讨论】:

  • 使用类变量。
  • 有几种方法:将它们转换为普通对象,重新创建Realm并重新获取,或者使用ThreadSafeReference
  • 我已经在使用一个类变量(在超类中)。但我得到了这个问题。在每个子类调用父类 init 时,领域实例被调用了两次!
  • 不要在线程之间传递托管的 RealmObject 和 RealmResults。
  • 为什么要在后台队列中创建一个领域,如问题所示?用例是什么? Realm 在每个线程的基础上缓存实例,因此多次调用 Realm() 几乎没有开销,因此这样做非常有效。

标签: ios swift iphone realm realm-mobile-platform


【解决方案1】:

您可以将领域字典用于线程,如下所示:

class RealmWrapper {

    var realm: Realm? {
        return realmsPool.realmForThread(Thread.current)
    }

    var realmsPool = RealmsPool()
}

class RealmsPool {

    var realms = [Thread: Realm]()

    func realmForThread(_ t: Thread) -> Realm? {

        if let realm = realms[t] {
            return realm
        }

        do {
            let newRealm = try Realm(configuration: config)
            self.realms[t] = newRealm
            return newRealm
        } catch {
            fatalError("\(error)")
        }
    }
}

【讨论】:

  • 谢谢,我喜欢这个主意。我已经通过确保在启动应用程序后在主线程中创建一个 Realm 实例来修复它。但是这个解决方案也很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-06
  • 2017-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-04
相关资源
最近更新 更多