ios - CoreData 在从同一线程读取获取的对象属性时崩溃
问题描述
下面,我有 3 个与 CoreData 以不同方式在不同线程中获取对象相关的代码片段。其中一种方法是当我在从 DB 中获取数据后尝试读取数据时使用 EXC_BAD_INSTRUCTION 崩溃,即使获取和读取是在同一个线程上完成的。
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)")
}
最后一个片段是导致问题的片段,而其他片段可以成功读取数据。
这就是我正在做的事情。
- 我创建了一个新的子上下文,类型为 privateQueueConcurrencyType,父设置为 mainContext
- 我首先使用 performAndWait 使用此上下文来获取和读取正常工作的数据。
- 然后我尝试使用 mainContext 在主线程中获取和读取。这也有效。
- 当我尝试在同一个线程上使用子上下文获取并在没有执行块的情况下读取时,即使我在同一个线程上,它也会崩溃。
该函数PPContactSyncHelper.contactsIfExistsWith
使用提供的上下文从 performAndWait 块内的 coredata 获取数据。
我在这里想念什么?
解决方案
对于托管对象上下文,您始终需要使用perform
or performAndWait
。除了一种情况:如果您使用主队列托管对象上下文并且在主队列上运行,则可以跳过这些方法。
在您的示例中:
- 示例 1 有效,因为您使用了
performAndWait
. 这是一个私有队列(不是主队列)上下文,并且您正确使用了它。 - 示例 2 有效,因为它是一个主队列上下文,并且您使用了
DispatchQueue.main.async
. 这是我上面提到的一个例外,所以你可以在哪里。 - 示例 3 不起作用,因为您使用的是私有队列上下文,但您没有使用
perform
orperformAndWait
。您需要在此处使用其中之一以避免崩溃。您与示例 1 在同一线程上,但这没关系。重要的是您的 Core Data 代码是否在上下文的队列中运行。
推荐阅读
- java - Selenium junit 问题 - 消息:没有这样的警报
- javascript - 在 React Native 应用程序中可按不可触摸
- ssas - SSAS 表格:部署元数据时出错。一对多关系中的列上的重复值
- linux - 如何为在linux中执行的命令设置命令执行超时
- java - @JSONField 它在春季启动时不起作用
- c# - 如何在 Xamarin 的 ViewCompat 中将我的 SimplestExploreByTouchHelper 设置为 AccessibilityDelegate?
- powerbi - 今年如何平均每个月 POWER BI
- vue.js - 如何通过特定坐标将Base64图像添加到pdf
- sql - ORA-00907: 缺少右括号 Hrk
- imagemagick - 使用 ImageMagick 裁剪索引 PNG 并保持与输入文件相同的调色板