Подтвердить что ты не робот

Где разместить "Core Data Stack" в приложении Cocoa/Cocoa Touch

В шаблоне данных ядра iPhone Apple помещает основной стек данных в делегат приложения.

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

Обычно вы инкапсулируете эту функциональность в свой класс или вы оставите ее в App Delegate?

4b9b3361

Ответ 1

Резюме: нет необходимости создавать singleton для управления стекю Core Data; действительно, это, скорее всего, будет контрпродуктивным.

Стек Core Data создается делегатом приложения. Важно отметить, однако, как показывают все примеры, стек (в основном контекст управляемого объекта) не извлекается непосредственно из стека (*). Вместо этого контекст передается в первый контроллер представления, а из них в контексте или управляемый объект передается от одного контроллера представления к следующему (как описано в Accessing стек основных данных). Это следует за базовым шаблоном для iPhone всех приложений: вы передаете данные или контроллер модели с одного контроллера просмотра на следующий.

Типичная роль синглтона, как описано здесь, является модельным контроллером. С помощью Core Data контекст управляемых объектов уже является модельным контроллером. Это также дает вам возможность доступа к другим частям стека, если это необходимо. Более того, в некоторых ситуациях (как описано в документации) вы можете использовать другой контекст для выполнения дискретного набора действий. Соответствующая единица валюты для контроллера вида, следовательно, обычно является контекстом управляемого объекта, в противном случае управляемым объектом. Использование и передача объекта singleton, который управляет стеком (и из которого вы извлекаете контекст), как правило, в лучшем случае вводит ненужный уровень косвенности и в худшем случае вводит излишнюю жесткость приложения.

(*) Ни один пример не извлекает контекст, используя:

[[UIApplication delegate] managedObjectContext];

Ответ 2

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

Ответ 3

Я оставляю логику основных данных в делете приложения по следующим причинам:

1) Я не вижу реального преимущества в продвижении этого кода в других классах: концепция делегирования полностью выполняется логикой основных данных, обрабатываемой делегатом приложения, поскольку основная модель данных на самом деле является фундаментальной частью вашего применение;

2) Во всем примере кода, который я видел, включая образцы Apple, материал основных данных обрабатывается делегатом App;

3) Даже в книгах Core Data обычно используется делегирование приложения с ключевым кодом, связанным с данными;

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

Ответ 4

Вопрос, который я задал себе, в вашем случае, - это "кто имеет" базовый стек данных "? Сами данные действительно являются областью приложения, не так ли? (C.F. Core Data на Mac, где у вас может быть приложение, способное работать с несколькими документами одновременно, поэтому стек Core Data принадлежит каждому документу.)

В любом приложении Cocoa/Cocoa Touch делегат приложения обычно является предпочтительным средством настройки поведения приложения, поэтому это естественное место для стека Core Data.

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

NSManagedObjectContext *context = [(MyAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];

То, что я обычно делаю в этих случаях, - это функции записи (а не методы), подобные этому:

NSManagedObjectContext *UIAppManagedObjectContext() {
    return [*(MyAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
}

Я пишу аналогичную функцию для NSPersistentStoreCoordinator и NSManagedObjectModel. Я поместил все эти файлы в файлы делегатов .h/.m, так как это тоже объекты уровня приложения.

Ответ 5

Я просто перечислил это в новом ответе. (Я отказался от своего предыдущего класса FJSCoreDataStack в пользу этого)

Моим новым способом справиться было использование категории в NSManagedObjectContext. Ive добавил следующие методы класса:

+ (NSManagedObjectContext *)defaultManagedObjectContext;
+ (NSManagedObjectContext *)scratchpadManagedObjectContext;
+ (NSManagedObjectModel *)managedObjectModel;
+ (NSPersistentStoreCoordinator *)persistentStoreCoordinator;
+ (NSString *)applicationDocumentsDirectory;

Это все держит из моего делегата приложения и дает односторонний доступ, если я захочу его использовать. Тем не менее, я все еще использую инъекцию зависимостей из App Delegate (как сказал mmalc, он вводит негибкость в мой код). Я просто переместил весь код "Core Data Stack" в категорию NSManagedObjectCOntext.

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

Также имеет отношение к разговору в мире iPhone (и может иметь отношение к вашей архитектуре): NSFetchedResultsController и построение NSFetchRequests

Ответ 6

Я сторонник того, что делегат приложения знает, где начинается модель, и имея модель, где находится Контекст управляемого объекта. "Основная информация" модели представляется мне как модель реализации модели, классы контроллера (например, делегат приложения) должны просто спросить "дать мне эту информацию о модели", и модель должна знать, как ответить этот вопрос. Поэтому наличие объекта Core Data, доступного через объект контроллера, похоже на простую абстракцию.