内存泄漏与大型核心数据批量插入在Swift中
我将数以万计的对象插入到我的核心数据实体中。 我有一个单独的NSManagedObjectContext
,每次添加对象时,我都会在托pipe对象上下文中调用save()
。 它可以工作,但在运行时,内存从大约27M增加到400M。 即使导入完成后,它仍然保持在400M。
有许多关于批量插入的SO问题,大家都说要读取Efficiently Importing Data ,但是在Objective-C中,我很难在Swift中find解决这个问题的实例。
有几件事情你应该改变:
- 创build一个单独的
NSPrivateQueueConcurrencyType
托pipe对象上下文,并在其中进行asynchronous插入。 - 插入每个实体对象后不要保存。 分批插入对象,然后保存每个批次。 批量大小可能类似于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 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在这个答案中帮助我理解和解决问题。