我正在将数万个对象插入到我的核心数据实体中。我有一个 NSManagedObjectContext
,每次添加对象时,我都会在托管对象上下文中调用 save()
。它可以工作,但是在运行时,内存会从大约 27M 增加到 400M。并且导入完成后还是400M。
有很多关于批量插入的 SO 问题,每个人都说要阅读 Efficiently Importing Data ,但它在 Objective-C 中,我无法在 Swift 中找到解决此问题的真实示例。
最佳答案
有几件事你应该改变:
- 创建一个单独的
NSPrivateQueueConcurrencyType
托管对象上下文并在其中异步插入。 - 插入每个实体对象后不要保存。分批插入对象,然后保存每批。批量大小可能类似于 1000 个对象。
- 每次批量插入和保存后,使用
autoreleasepool
和reset
清空内存中的对象。
这可能是这样工作的:
let managedObjectContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = (UIApplication.sharedApplication().delegate as! AppDelegate).persistentStoreCoordinator // or wherever your coordinator is
managedObjectContext.performBlock { // runs asynchronously
while(true) { // loop through each batch of inserts
autoreleasepool {
let array: Array<MyManagedObject>? = getNextBatchOfObjects()
if array == nil { break }
for item in array! {
let newObject = NSEntityDescription.insertNewObjectForEntityForName("MyEntity", inManagedObjectContext: managedObjectContext) as! MyManagedObject
newObject.attribute1 = item.whatever
newObject.attribute2 = item.whoever
newObject.attribute3 = item.whenever
}
}
// only save once per batch insert
do {
try managedObjectContext.save()
} catch {
print(error)
}
managedObjectContext.reset()
}
}
应用这些原则使我的内存使用率保持在较低水平,并使批量插入速度更快。
进一步阅读
- Efficiently Importing Data (旧的 Apple 文档链接已损坏。如果您能找到它,请帮我添加它。)
- Core Data Performance
- Core Data (大会后)
更新
上面的答案完全重写了。感谢评论中的@Mundi 和@MartinR 指出我原来答案中的错误。感谢@JodyHagins this answer帮助我理解和解决问题。
关于ios - Swift 中的大型 Core Data 批量插入导致内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32034100/