Совместное использование контекста управляемого объекта - PullRequest
3 голосов
/ 12 декабря 2011

Я пишу тестовую программу, в которой используется контроллер вкладок с несколькими представлениями вкладок.Программа загружает несколько файлов XML, анализирует и заполняет таблицы sqlite через Core Data.Переменные и функции Core Data находятся в файле делегата приложения после кода, созданного XCode.

Я начал с простой передачи переменной managedObjectContext каждому нужному подпредставлению, как я его инициализировал в делегате приложения, например:

FirstViewController *vc1;
vc1 = [[[FirstViewController alloc] initWithNibName:@"FirstView" bundle:nil] autorelease];
[vc1 setManagedObjectContext:self.managedObjectContext];

Однако у меня есть функция (resetData), которая удаляет все хранилище данных - удаляет файлы постоянного хранилища и устанавливает все переменные базовых данных (managedObjectContext, managedObjectModel, persistentStore и т. Д.) Равными nil,переинициализировать все.Это сделано для того, чтобы программа могла запускаться с нуля и перезагружать все данные из сети.Когда это происходит, подпредставления теперь указывают на старый managedObjectContext.

Каков наилучший способ обновить переменную managedObjectContext во всех подпредставлениях?Вручную обновить переменные managedObjectContext подпредставлений из функции resetData?Использовать NSNotificationCenter для отправки уведомления всем просмотрам?Полностью удаляет и повторно инициализирует все постоянные файлы хранилища?

В настоящее время я установил этот метод получения, который просто ссылается на делегат приложения во всех классах, которые должны ссылаться на MOC:

- (NSManagedObjectContext *)managedObjectContext {
    MyAppDelegate* ad = (MyAppAppDelegate*)[[UIApplication sharedApplication] delegate];
    return [ad managedObjectContext];
}

Я очень новичок в дизайне какао / iOS и пытаюсь найти наиболее правильный способ сделать это!То, что у меня сейчас работает, но мне интересно, есть ли невидимые подводные камни или будущие проблемы?Спасибо!

Ответы [ 3 ]

2 голосов
/ 12 декабря 2011

ИМХО передача управляемогоObjectContext в ViewControllers является хорошей практикой.Это облегчает тестирование и позволяет создавать многократно используемые ViewControllers.

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

Самый быстрый и эффективный способ удалить все объекты - это удалить файл хранилища.NSManagedObjectContext предлагает установщик для постоянного координатора хранилища.Вы пытались создать новый storeCoordinator с новым файлом, установить его в качестве storeCoordinator вашего MOC, а затем освободить старый координатор и удалить старый файл?В этом случае вам может потребоваться отправить Уведомление, поскольку все ViewControllers должны выпустить свои потенциально сохраненные управляемые объекты.

Еще одна идея, которая только что пришла мне в голову и которую я использовал ранее, - полностью удалить завершеннуюстек viewController, а затем воссоздать его, используя новый managedObjectContext.Вы можете легко загружать, анализировать и сохранять новые данные в своем собственном отдельном управляемом объекте управления объектами (с его собственным persistentStoreController и собственным хранилищем) в фоновом режиме.Как только это закончено, удалите все контроллеры из окна, отслеживая с контроллерами были показаны.Затем переместите новый файл хранилища, перезаписав старый, и заново создайте стек viewController, как это было раньше.Хотя это звучит как дорогая операция, это не так.В моем случае переключатель даже не был заметен в пользовательском интерфейсе.Преимущество перед сохранением viewControllers заключается в том, что гораздо менее вероятно, что старые управляемые объекты все еще где-то скрываются, что приводит к уменьшению кода, требующего дополнительного редактирования.Если ваши viewControllers уже настроены так, как рекомендует Apple, есть хорошие шансы, что этот переключатель будет «просто работать».

1 голос
/ 12 декабря 2011

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

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

@synthesize managedObjectContext = moc_ ;

Затем вы можете проверить:

- (NSManagedObjectContext *)managedObjectContext {
    MyAppDelegate* ad = (MyAppAppDelegate*)[[UIApplication sharedApplication] delegate];

    if(moc_ != [ad managedObjectContext]) {
          // NEW CONTEXT. DO ANYTHING NEEDED TO RESET OBJECT
    }

    // Use property to change value to ensure set rules (retain for example).
    [self setManagedObjectContext:[ad managedObjectContext]];

    return moc_;
}
0 голосов
/ 12 декабря 2011

Я обычно использую Singleton шаблон при работе с CoreData

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...