【问题标题】:Realm verify_thread crash领域 verify_thread 崩溃
【发布时间】:2016-07-26 09:41:55
【问题描述】:

我们正在经历以下崩溃

realm::Realm::verify_thread() const (shared_realm.cpp:274)

它偶尔发生,但来自我们代码中的不同流程。 我们发现的堆栈跟踪之一是

0x00000001003af7ec realm::Realm::verify_thread() const (shared_realm.cpp:274)
0x0000000100339d78 RLMGetObjects (RLMObjectStore.mm:83)
0x0000000100330130 +[RLMObject objectsWithPredicate:] (RLMObject.mm:150)
0x00000001000fa468 -[PrinterRepository getDefaultPrinter] (PrinterRepository.m:35)
0x00000001001faf3c -[PrintService handlePrintJobs] (PrintService.m:106)

我们在 [PrinterRepository getDefaultPrinter] 中的代码是

return [[Printer objectsWithPredicate:[NSPredicate predicateWithFormat:@"isDefault == 1"]] firstObject];

在本地我们还无法重现这种情况,我们只是在我们的 Beta 测试人员中不时看到这种情况发生。

我们的领域版本是 0.102.1

我们的 iOS 版本是 9.2.1、9.3.2 和 9.3.3

有人知道这次崩溃的原因吗?

【问题讨论】:

    标签: ios objective-c realm


    【解决方案1】:

    Managed Realm 对象是线程受限的。不允许在线程之间任意传递它们。当您在主线程上检索对象时,您只能在那里使用它。当您想将其传递给后台线程时,您需要在主线程上检索一个标识符,最好是指定为primaryKey 的属性,然后将其传递给后台线程。

    每当你违反它时,你都会遇到这样的失败。

    查看我们的the relevant chapter of our docs about "Passing Instances Across Threads"

    RLMObject 的非托管实例的行为与常规 NSObject 子类完全相同,并且可以安全地跨线程传递。

    RLMRealm、RLMResults 或 RLMArray 的实例或 RLMObject 的托管实例只能在创建它们的线程上使用,否则将引发异常*。这是 Realm 强制执行事务版本隔离的一种方式。否则,如果对象在不同事务版本的线程之间传递时,如果没有潜在的广泛关系图,将无法确定应该做什么。

    相反,有几种方法可以以可以在线程之间安全传递的方式表示实例。例如,具有主键的对象可以由其主键的值表示;或者一个 RLMResults 可以用它的 NSPredicate 或查询字符串来表示;或者一个 RLMRealm 可以用它的 RLMRealmConfiguration 来表示。然后目标线程可以使用其线程安全表示重新获取 RLMRealm、RLMObject、RLMResults 或 RLMArray。请记住,重新获取将在目标线程的版本中检索实例,该版本可能与原始线程不同。

    【讨论】:

    • 感谢您的回答,但对我来说,我们做错了什么并不是 100% 清楚。发生此问题时,我们将调用“objectsWithPredicate”或“allObjects”。我们没有将结果对象传递给另一个线程,因为崩溃发生在结果返回之前。还是我们对堆栈跟踪的解释有误?
    猜你喜欢
    • 1970-01-01
    • 2020-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多