我有一个SwiftUI项目,在这个项目中,我使用CoreData将从API获取的数据保存到设备中。我尝试批量插入实体,这很好,直到我意识到批量插入时的关系是"未触及的":
- 实体
Job
,与实体Tag.
具有一对多关系 - 与
Category
的一对一关系。 - 与
Type
的一对一关系。
我现在要做的是在后台任务中手动插入实体:
container.performBackgroundTask { context in
for job in jobs {
let jobToInsert = Job(context: context)
let type = JobType(context: context)
let category = Category(context: context)
jobToInsert.id = Int32(job.id)
....
do {
print("Inserting jobs")
try context.save()
} catch {
// log any errors
}
}
有没有什么方法可以提高性能,也许是用一种我不知道的方式来做呢?因为对于用户来说,当他们启动应用程序时,一个接一个地插入作业并不是一个很好的体验,因为首先,它需要很长的时间(超过2分钟),其次,我的UI在我插入实体时不会自动更新。
提前感谢!
编辑:我还看到内存增加,在截图后,在我停止进程之前,我看到内存为1.09GB
编辑2:这是我在尝试批量插入作业时使用的代码:
private func newBatchInsertRequest(with jobs: [JobCodable]) -> NSBatchInsertRequest {
var index = 0
let total = jobs.count
let batchInsert = NSBatchInsertRequest(
entity: Job.entity()) { (managedObject: NSManagedObject) -> Bool in
guard index < total else { return true }
if let job = managedObject as? Job {
let type = JobType(context: self.container.viewContext)
let category = Category(context: self.container.viewContext)
let data: JobCodable = jobs[index]
job.id = Int32(data.id)
...
return batchInsert
不幸的是,可能由于上下文的原因,无法建立关系,因为我在let category = Category(context: self.container.viewContext)
行中得到了Thread 13: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
1条答案
按热度按时间chhkpiq41#
您是否为插入的每个作业在上下文上调用
save()
?如果是这样,我将从那里开始-如果您想一次加载一组作业,您可以插入所有作业示例,设置关系,然后在最后(在循环之外)只调用save()
一次。这不仅可以保存你的时间,而且可以让所有的对象看起来像是同时出现在你的UI中。如果你不想这样,你可以尝试在循环中批量保存--例如,每一千个Job对象调用一次
save()
。