有一些事情你應該改變:
- 創建一個單獨的
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 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()
}
}
應用這些原則一直在我的內存使用量低,也讓大衆插入更快。
![enter image description here](https://i.stack.imgur.com/5BU3G.png)
進一步閱讀
更新
以上回答被完全重寫。感謝@Mundi和@MartinR在評論中指出我原來的答案中有錯誤。並感謝@JodyHagins在this answer幫助我理解和解決問題。
在您的代碼中,您似乎使用的是相同的託管對象上下文,而不是新的託管對象上下文。 – Mundi
在我上面的示例中,每個'while'循環都會重新創建託管對象上下文。 while循環表示一批插入,因此一個批處理使用相同的託管對象上下文,但下一批創建一個新的插入。我過去的問題是,我將上下文作爲類屬性,從不改變它。 – Suragch
@Suragch:這取決於如何在Application委託中實現'managedObjectContext'屬性,但是「常規」實現是一個lazy屬性,它在應用程序的生命週期中創建一次上下文。在這種情況下,你正在重複使用與Mundi所說的相同的上下文。 –