/ / Изтичане на паметта с голям вход за ядрото на данните в сървъра Swift-ios, бързи, ядро-данни, течове на паметта, bulkinsert

Изтичане на паметта с голям вход за ядрото на данните в сървъра Swift - ios, бързи, ядро-данни, течове на паметта, bulkinsert

Вмъквам десетки хиляди обекти в моята Core Data единица. Имам сингъл NSManagedObjectContext и викам save() върху контекста на управлявания обект всеки път, когато добавям обект. Тя работи, но докато тя работи, паметта продължава да нараства от около 27 милиона до 400 милиона. И то остава на 400 метра дори след като вносът е завършен.

въведете описанието на изображението тук

Има няколко въпроса за SO относно партидната вмъкване и всеки казва да прочете Ефективно импортиране на данни, но тя е в Цел-С и имам проблеми с намирането на истински примери в Swift, които да разрешат този проблем.

Отговори:

18 за отговор № 1

Има няколко неща, които трябва да промените:

  • Създайте отделно 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 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()
}
}

Прилагането на тези принципи продължи да намалява употребата на паметта, а масата се вмъква по-бързо.

въведете описанието на изображението тук

Актуализация

Горният отговор е напълно пренаписан. Благодарение на @Mundi и @MartinR в коментарите за посочване на грешка в първоначалния ми отговор. И благодарение на @ JodyHagins в този отговор за да ми помогне да разбера и да разреша проблема.