#iphone #objective-c #performance #core-data #import
#iPhone #objective-c #Производительность #core-data #импорт
Вопрос:
Я использую Core Data в своем приложении для iPhone для хранения около 1000 объектов. Каждому объекту назначается одна из 5 различных групп. Со временем объекты меняют группы, и внутри каждой группы порядок объектов в этих группах меняется и сохраняется в виде массива.
Затем я беру этот массив и использую атрибут ‘name’, чтобы сохранить его в plist. Когда я перезапускаю приложение, мой AppDelegate сканирует каждый объект в базе данных, затем сравнивает его с атрибутом ‘name’ в моем списке. Когда это завершится, у меня будет 5 массивов объектов core data, отсортированных по группам, каждый в исходном сохраненном порядке. Конечный результат хорош. Время, необходимое для выполнения этой задачи, не.
Я хочу сделать это быстрее. Если бы я мог сохранить фактический массив объектов core data в свой plist, я бы это сделал. Но я могу сохранить только атрибуты к нему.
У Apple есть документация по эффективному внедрению функции поиска или создания, в частности, этот код:
// get the names to parse in sorted order
NSArray *employeeIDs = [[listOfIDsAsString componentsSeparatedByString:@"n"]
sortedArrayUsingSelector: @selector(compare:)];
// create the fetch request to get all Employees matching the IDs
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
[fetchRequest setEntity:
[NSEntityDescription entityForName:@"Employee" inManagedObjectContext:aMOC]];
[fetchRequest setPredicate: [NSPredicate predicateWithFormat: @"(employeeID IN %@)", employeeIDs]];
// make sure the results are sorted as well
[fetchRequest setSortDescriptors: [NSArray arrayWithObject:
[[[NSSortDescriptor alloc] initWithKey: @"employeeID"
ascending:YES] autorelease]]];NSError *error = nil;
NSArray *employeesMatchingNames = [aMOC
executeFetchRequest:fetchRequest error:amp;error];
Однако fetchRequest устанавливает SortDescriptor и выполняет сортировку с использованием ключа ‘EmployeeID’. Я пробовал это. У меня есть атрибут ID key, и я могу сохранять позицию индекса массива при добавлении объекта в группу. Однако, поскольку объекты добавляются и удаляются из каждой группы, индекс объекта постоянно меняется. Поэтому после каждого изменения мне пришлось бы повторно сканировать каждую группу и сбрасывать индекс. Для меня это просто перенесло бы мою проблему скорости в другую часть моей программы.
Мои вопросы таковы: есть ли лучший способ сохранить индексную позицию объектов в массиве? или есть другое место, где я могу хранить массив объектов core data? Однако, если я сделал последнее, поскольку мое приложение уже есть в AppStore, я понимаю, что если я добавлю атрибуты или таблицы в базу данных, это может вызвать проблемы при обновлении пользователя.
Надеюсь, я хорошо это объяснил. Буду признателен за любую помощь, спасибо.
Ответ №1:
Вы усложняете этот способ. Проблема, которую вы хотите решить, т. Е. упорядочивание объектов на основе значения атрибута, является очень распространенной потребностью, например, для каждого отдельного tableview требуется этот тип упорядочения.
Упорядочивание — это то, почему вы можете предоставить один или несколько дескрипторов сортировки для выборки. В этом случае вы хотите упорядочить по employeeID
атрибуту, поэтому вы просто предоставляете сортировку по этому ключу. Массив, возвращаемый выборкой, будет отсортирован по этому атрибуту.
Когда вы добавляете или удаляете объекты, вы просто повторно запускаете выборку либо напрямую, либо с помощью уведомлений. Если вы используете NSFetchedResultsController, все это обрабатывается автоматически.
Если вам нужен какой-то произвольный порядок, скажем, список избранных пользователя, тогда вам нужно смоделировать этот произвольный порядок непосредственно в модели данных. Существуют различные способы сделать это в зависимости от конкретного необходимого типа заказа.
Вот хорошее эмпирическое правило при проектировании с использованием Core Data: Если у вас есть какая-либо другая структура данных для хранения или упорядочивания управляемых объектов помимо массивов, возвращаемых выборками, вы сделали что-то неправильно.
При правильном использовании Core Data может управлять всей моделью данных без каких-либо внешних структур. Если вы обнаружите, что добавляете дополнительные структуры данных к основным данным, значит, вы что-то упустили в своей модели данных.
Ответ №2:
На iPhone нет другого способа поддерживать упорядоченную коллекцию, кроме сохранения индекса. Это свойство является целым числом, правильно?
Если вы добавляете атрибуты, что происходит, вам нужно настроить persistantStoreCoordinator таким образом, чтобы он пытался выполнить автоматическую миграцию. Однако, если вы никогда раньше не создавали другую версию модели, это будет непросто. Вам следует попробовать это и посмотреть, сможете ли вы заставить это работать, поскольку вам, вероятно, когда-нибудь придется это сделать…
По моим ощущениям в CoreData, миграция достаточно сложная, вы также всегда должны хранить любые пользовательские данные в чем-то вроде списка, из которого вы можете заново создать базу данных. Похоже, вы, возможно, уже это делаете? Если это так, вы можете проверить при создании persistantStoreCoordinator, произошел ли сбой, и если да, то удалите существующую базу данных, снова создайте persistantStoreCoordinator и заполните эту базу данных из своих списков.