从同一线程读取获取的对象属性时 CoreData 崩溃

下面,我有 3 个与 CoreData 以不同方式在不同线程中获取对象相关的代码片段。其中一种方法是当我在从数据库中获取数据后尝试读取数据时 EXC_BAD_INSTRUCTION 崩溃,即使获取和读取是在同一线程上完成的。

QEventLoop

最后一个片段是导致问题的片段,而其他片段可以成功读取数据。

这就是我正在做的。

  1. 我创建了一个新的子上下文,其类型为 privateQueueConcurrencyType,父上下文设置为 mainContext
  2. 我首先使用此上下文使用 performAndWait 来获取和读取正常工作的数据。
  3. 然后我尝试使用 mainContext 在主线程中获取和读取。这也有效。
  4. 当我尝试在同一线程上使用子上下文获取并在没有执行块的情况下读取时,即使我在同一线程上它也会崩溃。

函数 print("hello: current thread is \(Thread.current)") let moc = self.getchildmoc() moc.performAndWait { let contacts = PPContactSyncHelper.contactsIfExistsWith(connectIds: connectIds,moc: moc) contacts.forEach { contact in print("hello: 2. current thread is \(Thread.current)") print("hello: \(contact.connectId)") } } DispatchQueue.main.async { let abContacts = PPContactSyncHelper.contactsIfExistsWith(connectIds: connectIds,moc: self.mainContext) abContacts.forEach { abContact in print("hello: \(abContact.connectId)") } } let contacts = PPContactSyncHelper.contactsIfExistsWith(connectIds: connectIds,moc: moc) contacts.forEach { contact in print("hello: 2. current thread is \(Thread.current)") print("hello: \(contact.connectId)") } 使用提供的上下文从 performAndWait 块内的 coredata 中获取数据。

我在这里遗漏了什么?

leigang_ 回答:从同一线程读取获取的对象属性时 CoreData 崩溃

对于托管对象上下文,您始终需要使用 [\+\-\*\/\%\^]perform。除了一种情况:如果您使用主队列管理对象上下文并且您正在主队列上运行,则可以跳过这些方法。

在您的示例中:

  • 示例 1 有效,因为您使用了 performAndWait。这是一个私有队列(不是主队列)上下文,您正确使用了它。
  • 示例 2 有效,因为它是一个主队列上下文并且您使用了 performAndWait。这是我上面提到的一个例外,所以你可以在哪里。
  • 示例 3 不起作用,因为您使用的是私有队列上下文,但没有使用 DispatchQueue.main.asyncperform。您需要在此处使用其中之一以避免崩溃。您与示例 1 在同一线程上,但这无关紧要。重要的是您的 Core Data 代码是否在上下文的队列中运行。
,

NSManagedObjectContext 是如何创建的以及它与哪个线程相关联的理解是不正确的。当使用 NSManagedObjectContext 在特定线程上创建 initWithConcurrencyType 时,并不意味着该特定线程是 NSManagedObjectContext 的线程。它只是在那个线程上创建的,没有别的。只有当我们在 perform 上调用 performAndWaitNSManagedObjectContext 时,我们传递的块才会在 NSManagedObjectContext 的线程上运行。结果描述了相同的场景。

但是,如果 NSManagedObjectContext 仅使用 init 创建,没有并发类型,则当前线程将是 NSManagedObjectContext 的线程。

本文链接:https://www.f2er.com/12424.html

大家都在问