在Swift中使用大型Core Data批处理插入内存泄漏

Sur*_*gch 11 memory-leaks bulkinsert core-data ios swift

我将数以万计的对象插入到我的Core Data实体中.我有一个NSManagedObjectContext,save()每次添加对象时我都会调用托管对象上下文.它可以工作,但在运行时,内存从大约27M增加到400M.即使在导入完成后它仍然保持在400M.

在此输入图像描述

关于批量插入有很多SO问题,每个人都说阅读Efficiently Importing Data,但是它在Objective-C中,我很难在Swift中找到解决这个问题的真实例子.

Sur*_*gch 25

你应该改变一些事情:

  • 创建一个单独的NSPrivateQueueConcurrencyType托管对象上下文,并在其中异步执行插入操作.
  • 插入每个实体对象后不要保存.批量插入对象,然后保存每个批次.批量大小可能类似于1000个对象.
  • 每次批量插入和保存后,使用autoreleasepoolreset清空内存中的对象.

以下是这可能如何工作:

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()
    }
}
Run Code Online (Sandbox Code Playgroud)

应用这些原则可以降低我的记忆力,并使质量插入更快.

在此输入图像描述

进一步阅读

更新

上面的答案完全被重写了.感谢@Mundi和@MartinR在评论中指出我原来答案中的错误.感谢@JodyHagins在这个答案中帮助我理解和解决问题.