Я работаю над частью кода для приложения для iPhone, которое выбирает набор данных из сервера и создает объекты из них на клиенте. Это заканчивает тем, что создало примерно 40 000 объектов. Они не отображены пользователю, я просто должен создать экземпляры NSManagedObject и сохранить их к персистентному устройству хранения данных.
Я нахожусь неправильно в размышлении, что единственный способ сделать это должно создать отдельный объект, затем сохраните контекст? лучше создать объекты внезапно, затем так или иначе сохранить их к контексту после того, как они будут созданы и сохранены в некотором наборе или массиве? Если так, можно показать некоторый пример кода для того, как это сделано, или укажите на меня в направлении для кодирования, где это сделано?
Сами объекты являются относительно прямыми моделями со строкой или целочисленными атрибутами и не содержат сложных отношений.
В любом случае, не сохраняйте после вставки каждого объекта или будьте готовы к ужасным выступлениям.
Вот код, который я использую для заполнения репозитория 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];
}
Также не забудьте сохранить в последний раз после цикла.
Также имейте в виду, что существует ошибка, которая приведет к сбою, если выполнены все три из следующих условий:
Обходной путь в приведенном выше коде заключается в инициализации numUnsavedAirports
в MAX_UNSAVED_AIRPORTS_BEFORE_SAVE
, чтобы гарантировать, что первое сохранение произойдет после первой вставки .
Надеюсь, это поможет.
Вероятно, лучше создать один объект и сохранить контекст.
У вас 40к объектов. Скажем, создание одного NSManagedObject занимает x единиц времени. 40kx единиц времени, вероятно, можно измерить. Пока происходит создание объекта, пользователь по какой-то причине может выйти из приложения; пользователи непредсказуемы. В следующий раз, когда ваше приложение запустится, вы повторите весь процесс заново. Было бы нежелательно создавать 39 999-й объект только для того, чтобы пользователь вышел из приложения и потерял всю свою работу.
Если бы ваше приложение создавало каждый объект и сохраняло его, вы могли бы немного ускорить этот процесс. Приложение запускается и проверяет, смогло ли оно выполнить задачу при последнем запуске. Если задача была незавершенной, она могла попытаться продолжить с того места, где была остановлена.
Метод создания и сохранения одного объекта может занять больше времени, но с большей вероятностью выполнит задачу.
Что касается потребления памяти, это также минимизирует состояние памяти вашего приложения. Контекст не отслеживает 40 КБ объектов в памяти.
Сохранение после каждого объекта приведет к очень плохой производительности.У вас должен быть баланс сохранений, возможно, каждые 100 (тестирование определит золотую середину), а затем отслеживать, где вы находитесь в процессе обработки, когда пользователь завершает работу.
У вас есть время при выходе для сохранения состояния, так что вы можете легко сохранить свою позицию в процессе обработки данных (5 блоков из 100 сохраненных) и продолжить с того места, где вы остановились.
При сохранении каждого объекта по отдельности диск будет забиваться и приложение замедлится до ползания.