ios - Swift 中的大型 Core Data 批量插入导致内存泄漏

标签 ios swift core-data memory-leaks bulkinsert

我正在将数万个对象插入到我的核心数据实体中。我有一个 NSManagedObjectContext,每次添加对象时,我都会在托管对象上下文中调用 save()。它可以工作,但是在运行时,内存会从大约 27M 增加到 400M。并且导入完成后还是400M。

enter image description here

有很多关于批量插入的 SO 问题,每个人都说要阅读 Efficiently Importing Data ,但它在 Objective-C 中,我无法在 Swift 中找到解决此问题的真实示例。

最佳答案

有几件事你应该改变:

  • 创建一个单独的 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()
    }
}

应用这些原则使我的内存使用率保持在较低水平,并使批量插入速度更快。

enter image description here

进一步阅读

  • 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/

相关文章:

ios - 如何对 Xcode 中断言失败的代码运行单元测试?

swift - 核心数据从日志中单独显示属性

iphone - 构建具有对多深度关系的 NSPredicate 的更好方法是什么?

ios - 如果按下电源按钮,CallKit 集成视频通话应用程序结束通话后

ios - 在 iOS 中收到 APNS 时打开 View Controller

iOS Vapor Js 未找到

ios - UIViewController.addChild() 是如何工作的

ios - 使用自动布局的可扩展 UITableView 单元会导致 UIViewAlertForUnsatisfiableConstraints

ios - 应用程序更新和核心数据

ios - 无法将文件保存在 Swift 2 文档目录内的文件夹中