Пакетная вставка iOS CoreData? - PullRequest
23 голосов
/ 10 ноября 2010

В моем приложении для iPhone мне нужно вставить ~ 2000 записей в базовые данные, прежде чем пользователь сможет использовать какие-либо функции приложения.Я загружаю записи в CoreData из локального файла JSON.Этот процесс занимает много времени (2,5+ минуты), но должен происходить только один раз (или каждое ~ 10 приложений открывается для получения обновленных данных).

Есть ли пакетная вставка для Core Data?Как я могу ускорить этот процесс вставки?

Если я не могу ускорить его с помощью Core Data, каковы другие рекомендуемые варианты?

Ответы [ 3 ]

28 голосов
/ 10 ноября 2010

Ознакомьтесь с главой Эффективный импорт данных из Руководства по программированию основных данных.

У меня сейчас такие же проблемы, как и у вас, только я вставляю 10000 объектов, и это занимает около 30 секунд, что все еще медленно для меня. Я делаю [managedObjectContext save] для каждых 1000 управляемых объектов, вставленных в контекст (другими словами, мой размер пакета равен 1000). Я экспериментировал с 30 различными размерами партий (от 1 до 10000), и 1000, кажется, является оптимальным значением в моем случае.

5 голосов
/ 16 августа 2015

Я искал ответ на похожий вопрос , когда наткнулся на этот.Ответ @ VladimirMitrovic был полезен в то время, когда я знал, что не следует каждый раз сохранять контекст, но я также искал пример кода.

Теперь, когда он у меня есть, я приведу приведенный ниже код, чтобы другие люди могли видеть, как это выглядит при выполнении пакетной вставки.

// set up a managed object context just for the insert. This is in addition to the managed object context you may have in your App Delegate.
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. Your implementation may vary.

        autoreleasepool { // auto release objects after the batch save

            let array: Array<MyManagedObject>? = getNextBatchOfObjects() // The MyManagedObject class is your entity class, probably named the same as MyEntity
            if array == nil { break } // there are no more objects to insert so stop looping through the batches

            // insert new entity object
            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()
    }
}
0 голосов
/ 23 марта 2017

Objective-C

Версия для @Suragch anwser

NSManagedObjectContext * MOC = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
MOC.persistentStoreCoordinator = YOURDB.persistentStoreCoordinator;
[MOC performBlock:^{ 
   // DO YOUR OPERATION
 }];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...