我们遇到了以下崩溃
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
有人知道这次崩溃的原因吗?
答案 0 :(得分:1)
Managed Realm对象受线程限制。你不允许在线程之间任意传递它们。当您在主线程上检索对象时,您只能在那里使用它。当你想将它传递给后台线程时,你需要在主线程上检索一个标识符,理想情况下是指定为primaryKey
的属性,并将其传递给后台线程。
每当你违反此规定时,你就会失败。
请参阅我们的the relevant chapter of our docs about "Passing Instances Across Threads":
RLMObjects的非托管实例的行为与常规NSObject子类完全相同,并且可以安全地传递线程。
RLMRealm,RLMResults或RLMArray的实例或RLMObject的托管实例只能在创建它们的线程上使用,否则抛出异常*。这是Realm强制执行事务版本隔离的一种方式。否则,当在没有可能广泛的关系图的情况下在不同事务版本的线程之间传递对象时,将无法确定应该执行的操作。
相反,有几种方法可以在线程之间安全地传递方式来表示实例。例如,具有主键的对象可以由其主键的值表示;或者RLMResults可以用其NSPredicate或查询字符串表示;或者RLMRealm可以由其RLMRealmConfiguration表示。然后,目标线程可以使用其线程安全表示重新获取RLMRealm,RLMObject,RLMResults或RLMArray。请记住,重新获取将检索目标线程版本的实例,该实例可能与原始线程不同。