我注意到访问领域对象的许多问题,我认为我的解决方案将解决这个问题。
所以我写了一个简单的帮助方法,像这样:
public func write(completion: @escaping (Realm) -> ()) {
DispatchQueue(label: "realm").async {
if let realm = try? Realm() {
try? realm.write {
completion(realm)
}
}
}
}
字符串
我认为完成块会很好,因为每次我写对象或更新它时,我都会使用上面的方法。
很不幸,我得到了错误:
libc++abi.dylib: terminating with uncaught exception of type realm::IncorrectThreadException: Realm accessed from incorrect thread.
型
5条答案
按热度按时间n9vozmp41#
Realm
和Object
的数组是线程包含的。它们不能在线程之间传递,否则会发生异常。由于在创建队列的同时将
completion
块本身传递给后台队列(正如Dave韦斯顿所说),该块中的任何Realm对象肯定不会在同一线程上创建,这可以解释此错误。就像Dave说的,每次调用该方法时都要创建一个新的调度队列。但要扩展到这一点,iOS也不能保证在同一线程上始终调用单个队列。
因此,Realm的最佳实践是每次要在同一线程上执行新操作时,都在该线程上重新创建Realm对象。Realm在每个线程的基础上内部缓存
Realm
的示例,因此多次调用Realm()
所涉及的开销非常小。要更新特定对象,可以使用the new
ThreadSafeReference
feature在后台线程上重新访问同一对象。字符串
qlzsbp2j2#
方法在每次调用时都会创建一个新的
DispatchQueue
。DispatchQueue(name:"")
是一个初始化器,而不是一个查找。如果你想确保你总是在同一个队列上,你需要存储一个对那个队列的引用并分派到它。您应该在设置Realm时创建队列,并将其存储为执行设置的类的属性。
cmssoen23#
也许这对某人有帮助(因为我花了几个小时寻找解决方案)
在我的例子中,我在后台将JSONMap到模型(导入ObjectMapper_Realm)时发生了崩溃。同时,主线程上分配了一个realm示例。
px9o7tmv4#
通常情况下,当你在不同的线程中初始化它并试图从不同的线程访问或修改时,它会发生。只需放置一个调试器来查看初始化的线程并尝试使用相同的线程。
kjthegm65#
在我使用Realm情况下,不要使用PMAC,只使用同步