Где разместить "стек основных данных" в приложении Cocoa / Cocoa Touch


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

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

обычно ли вы инкапсулируете эту функциональность в свой собственный класс или оставляете ее в делегате приложения?

6 67

6 ответов:

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

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

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

(*) ни один пример не извлекает контекст с помощью:

[[UIApplication delegate] managedObjectContext];

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

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

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

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

3) даже в книгах основных данных распространена практика, когда делегат приложения обрабатывает код, связанный с основными данными;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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