Память эффективный способ вставить массив объектов с Базовыми Данными

Я работаю над частью кода для приложения для iPhone, которое выбирает набор данных из сервера и создает объекты из них на клиенте. Это заканчивает тем, что создало примерно 40 000 объектов. Они не отображены пользователю, я просто должен создать экземпляры NSManagedObject и сохранить их к персистентному устройству хранения данных.

Я нахожусь неправильно в размышлении, что единственный способ сделать это должно создать отдельный объект, затем сохраните контекст? лучше создать объекты внезапно, затем так или иначе сохранить их к контексту после того, как они будут созданы и сохранены в некотором наборе или массиве? Если так, можно показать некоторый пример кода для того, как это сделано, или укажите на меня в направлении для кодирования, где это сделано?

Сами объекты являются относительно прямыми моделями со строкой или целочисленными атрибутами и не содержат сложных отношений.

7
задан randombits 9 April 2010 в 17:01
поделиться

3 ответа

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

Вот код, который я использую для заполнения репозитория Core Data при первом запуске.

#define MAX_UNSAVED_AIRPORTS_BEFORE_SAVE 1000
int numAirports = 0;
int numUnsavedAirports = MAX_UNSAVED_AIRPORTS_BEFORE_SAVE; // *** bug. see below
for (NSDictionary *anAirport in initialAirports) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    Airport *newAirport = [NSEntityDescription insertNewObjectForEntityForName:@"Airport" inManagedObjectContext:managedObjectContext];

    newAirport.city         = [anAirport objectForKey:@"city"];
    newAirport.code         = [anAirport objectForKey:@"code"];
    newAirport.name         = [anAirport objectForKey:@"name"];
    newAirport.country_name = [anAirport objectForKey:@"country_name"];
    newAirport.latitude     = [NSNumber numberWithDouble:[[anAirport objectForKey:@"latitude"] doubleValue]];
    newAirport.longitude    = [NSNumber numberWithDouble:[[anAirport objectForKey:@"longitude"] doubleValue]];
    newAirport.altitude     = [NSNumber numberWithDouble:[[anAirport objectForKey:@"altitude"] doubleValue]];

    numAirports++;
    numUnsavedAirports++;
    if (numUnsavedAirports >= MAX_UNSAVED_AIRPORTS_BEFORE_SAVE) {
        if (![managedObjectContext save:&error]) {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
        numUnsavedAirports = 0;
    }
    [pool release];
}

Также не забудьте сохранить в последний раз после цикла.

Также имейте в виду, что существует ошибка, которая приведет к сбою, если выполнены все три из следующих условий:

  1. Репозиторий пуст
  2. У вас есть UITableView с разделами
  3. Ваше первое сохранение сохраняет больше чем один объект.

Обходной путь в приведенном выше коде заключается в инициализации numUnsavedAirports в MAX_UNSAVED_AIRPORTS_BEFORE_SAVE , чтобы гарантировать, что первое сохранение произойдет после первой вставки .

Надеюсь, это поможет.

5
ответ дан 7 December 2019 в 03:13
поделиться

Вероятно, лучше создать один объект и сохранить контекст.

У вас 40к объектов. Скажем, создание одного NSManagedObject занимает x единиц времени. 40kx единиц времени, вероятно, можно измерить. Пока происходит создание объекта, пользователь по какой-то причине может выйти из приложения; пользователи непредсказуемы. В следующий раз, когда ваше приложение запустится, вы повторите весь процесс заново. Было бы нежелательно создавать 39 999-й объект только для того, чтобы пользователь вышел из приложения и потерял всю свою работу.

Если бы ваше приложение создавало каждый объект и сохраняло его, вы могли бы немного ускорить этот процесс. Приложение запускается и проверяет, смогло ли оно выполнить задачу при последнем запуске. Если задача была незавершенной, она могла попытаться продолжить с того места, где была остановлена.

Метод создания и сохранения одного объекта может занять больше времени, но с большей вероятностью выполнит задачу.

Что касается потребления памяти, это также минимизирует состояние памяти вашего приложения. Контекст не отслеживает 40 КБ объектов в памяти.

1
ответ дан 7 December 2019 в 03:13
поделиться

Сохранение после каждого объекта приведет к очень плохой производительности.У вас должен быть баланс сохранений, возможно, каждые 100 (тестирование определит золотую середину), а затем отслеживать, где вы находитесь в процессе обработки, когда пользователь завершает работу.

У вас есть время при выходе для сохранения состояния, так что вы можете легко сохранить свою позицию в процессе обработки данных (5 блоков из 100 сохраненных) и продолжить с того места, где вы остановились.

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

3
ответ дан 7 December 2019 в 03:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: