RLMException when trying to perform Realm transaction with Grand Central Dispatch

浪子不回头ぞ 提交于 2019-12-08 08:18:26

As there is in general no fixed association between threads and queues (without the main queue, which only runs on the main thread and vice-versa), you can't just retrieve a RLMRealm instance by dispatching to your queue and cache it. GCD gives no guarantee, that the same queue will be executed by the same thread again.

I'd recommend to refer to your Realm instead by a non-cached factory method:

var realmdb : RLMRealm {
  return RLMRealm.defaultRealm()
}

No worries, the factory method defined on RLMRealm itself implements already a caching strategy, so this operation is not too expensive and you can still cache the instance in a local var per each usage.

If you want to pass it around to decouple classes from each other, you can still write it as a function type:

var realmdb : () -> RLMRealm {
    return { RLMRealm.defaultRealm() }
}

You should replace this

dispatch_async(realmQueue) {

    realmdb.beginWriteTransaction()
    realmdb.addObject(channelEnvironment)
    realmdb.commitWriteTransaction()

}

With

dispatch_async(realmQueue) {
    autoreleasepool {
        let realmdb = try! Realm()
        realmdb.beginWriteTransaction()
        realmdb.addObject(channelEnvironment)
        realmdb.commitWriteTransaction()
    }
}

This way you ensure that the Realm instance is closed, and that you create a Realm instance that belongs to that given thread. A Realm instance can only be accessed on the thread where it was created.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!