Шаблон проектирования CoreData: сохранение одного объекта из многих или сколько NSPessistentObjectContexts мне нужно иметь? - PullRequest
0 голосов
/ 08 июня 2009

Я конвертирую приложение из объектов SQLitePersistentObjects в CoreData.

В приложении есть класс, для которого я генерирую множество * экземпляров из файла XML, полученного с моего сервера. Пользовательский интерфейс может инициировать действия, которые потребуют от меня сохранения некоторых * этих объектов до следующего вызова приложения.

За исключением наличия одного NSManagedObjectContext для каждого из этих объектов (совместно используется только с их подчиненными объектами, которые могут включать большие двоичные объекты). Я не могу понять, каким образом я могу иметь мелкозернистый контроль (т.е. на уровне объектов) над тем, какие объекты сохраняются. Если я пытаюсь создать единый контекст для всех вновь создаваемых объектов, я получаю исключение, когда пытаюсь переместить один из моих объектов в новый контекст, чтобы я мог сохранить его самостоятельно. Я предполагаю, что это потому, что принадлежащие ему объекты остаются в «старом» контексте.

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

Итак:

  1. Я что-то упустил из-за того, как должно быть спроектировано приложение CoreData?
  2. Является ли наличие контекста для объекта хорошим шаблоном проектирования?
  3. Есть ли лучший способ перемещать объекты между контекстами, чтобы избежать 2?

*, где «многие» означают «десятки, может быть, сотни, а не тысячи», а «некоторые» по крайней мере на один порядок меньше, чем «многие»

Также кросс опубликован на форумах Apple .

1 Ответ

5 голосов
/ 08 июня 2009

Базовые данные на самом деле не являются структурой персистентности объекта. Это является структурой управления графами объектов, которая, как оказалось, способна сохранить этот граф на диске (см. этот предыдущий ответ SO для получения дополнительной информации). Поэтому попытка использовать базовые данные для сохранения только некоторых объектов в графе объектов будет работать против структуры. Базовые данные скорее всего будут управлять всем графом всех объектов, которые вы собираетесь создать. Итак, варианты не идеальны, но я вижу несколько (включая некоторые, которые вы упомянули):

  1. Вы можете создать все объекты в контексте Core Data, а затем удалить те, которые вы не хотите сохранять. До тех пор, пока вы не сохраните контекст, все в памяти, так что не будет никакого «возврата к базе данных», как вы предлагаете. Даже после сохранения на диск Core Data очень хорошо справляется с кэшированием экземпляров в кеше строк контекста, и на удивление мало времени, чтобы просто позволить ему делать свое дело и не беспокоиться о том, что на диске и что в памяти.
  2. Если вы можете сначала создать все объекты, а затем выполнить всю обработку в памяти, прежде чем решать, какие объекты сохранять, вы можете создать один NSManagedObjectContext с координатором постоянного хранилища, имеющего только постоянное хранилище в памяти. Когда вы решаете, какие объекты сохранять, вы можете добавить постоянное (XML / двоичное / SQLite) хранилище в координатор постоянного хранилища, назначить объекты, которые вы хотите сохранить в этом хранилище (используя (void)assignObject:(id)object toPersistentStore:(NSPersistentStore *)store контекста), а затем сохранить контекст.
  3. Вы можете создать все объекты вне Базовых данных, а затем скопировать объекты для сохранения в контекст Базовых данных.
  4. Вы можете создать все объекты в одном контексте в памяти и написать свои собственные методы, чтобы скопировать свойства и связи этих объектов в новый контекст, чтобы сохранить только те экземпляры, которые вы хотите. Если сущности в вашей модели не имеют много связей, это не так сложно (см. на этой странице с советами по переносу объектов из одного хранилища в другое с использованием многоходового подхода; в нем описывается методика контекст управления версиями управляемых объектных моделей и больше не требуется в 10.5 для этой цели, но этот метод также применим к вашему варианту использования).

Лично я бы выбрал вариант 1 - пусть Core Data сделает свое дело, включая управление удалениями из графа объектов.

...