Где разместить "стек основных данных" в приложении Cocoa / Cocoa Touch
в шаблоне для iPhone основных данных, Apple помещает параметры товара в приложении делегата.
моя первоначальная склонность, однако, состоит в том, чтобы переместить этот код в свой собственный класс, ответственность которого заключается в обработке управления основным стеком данных.
обычно ли вы инкапсулируете эту функциональность в свой собственный класс или оставляете ее в делегате приложения?
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 "модели кажутся мне деталями реализации модели, классы контроллера (например, делегат приложения) должны просто спросить" дайте мне эту информацию о модели", и модель должна знать, как ответить на этот вопрос. Таким образом, основной объект данных, доступных через объект контроллер выглядит как дырявое абстракция.