内存泄漏与大型核心数据批量插入在Swift中

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

在这里输入图像说明

有许多关于批量插入的SO问题,大家都说要读取Efficiently Importing Data ,但是在Objective-C中,我很难在Swift中find解决这个问题的实例。

有几件事情你应该改变:

  • 创build一个单独的NSPrivateQueueConcurrencyType托pipe对象上下文,并在其中进行asynchronous插入。
  • 插入每个实体对象后不要保存。 分批插入对象,然后保存每个批次。 批量大小可能类似于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 newEntityObject = 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() } } 

应用这些原则保持我的记忆体使用率低,也使质量插入更快。

在这里输入图像说明

进一步阅读

  • 高效地导入数据(旧的苹果文档链接被破坏,如果你能find它,请帮我添加它。)
  • 核心数据性能
  • 核心数据 (大会职位)

更新

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