Как поделиться ManagedObjectContext при использовании UITabBarController - PullRequest
13 голосов
/ 15 января 2010

У меня есть приложение для iPhone с MainWindow.xib, содержащим UITabBarController, который, в свою очередь, имеет UINavigationController и пользовательский подкласс UIViewController в своем массиве ViewControllers. Корневой контроллер представления для UINavigationController и пользовательский контроллер представления загружаются из других файлов XIB.

Приложение использует основные данные, стек инициализируется в делегате приложения (согласно соглашению ).

Делегат приложения добавляет UITabBarController в окно:

- (void)applicationDidFinishLaunching:(UIApplication *)application {        
    // Configure and show the window
    [window addSubview:[tabBarController view]];
    [window makeKeyAndVisible];
}

Я понимаю, что мне нужно передать указатель на ManagedObjectContext, созданный в делегате приложения, но я не знаю, как поступить (даже читая все хорошие комментарии по теме здесь и здесь ):

  • Распространять ли ManagedObjectContext на UITabBarController и оттуда на отдельные контроллеры представления, и если да, то как?
  • Или я должен распространить ManagedObjectContext непосредственно на корневой контроллер представления UINavigationController и на пользовательский контроллер представления, и как мне это сделать?

Думаю, я недостаточно хорошо понимаю, как работать с UITabBarController.

Ответы [ 9 ]

14 голосов
/ 15 января 2010

В идеале вы хотите передать либо NSManagedObjectContext, NSFetchedResultsController, либо соответствующий NSManagedObject "вниз" в UIViewController. Это позволяет «родителю» контролировать «ребенка» и определять, что должен иметь ребенок. Это создает более слабосвязанную конструкцию и позволяет легко переупорядочивать UIViewController экземпляров по мере необходимости. Это также облегчает повторное использование UIViewController.

В дизайне вида вкладок он ничем не отличается. Ваш AppDelegate передает NSManagedObjectContext тому, кто отвечает за создание начальных UIViewController экземпляров, которые входят в UITabBarController. В свою очередь, создатель передает соответствующую информацию (NSManagedObject, NSFetchedResultsController и / или NSManagedObject экземпляры) в экземпляры UIViewController при их создании.

11 голосов
/ 15 января 2010

Если вы хотите использовать метод внедрения зависимостей для передачи контекста управляемого объекта с помощью контроллера панели вкладок, более надежным решением было бы зацикливание на всех контроллерах представления в applicationDidFinishLaunching:

for (id vc in tabBarController.viewControllers) {
    [vc setManagedObjectContext:self.managedObjectContext];
}
1 голос
/ 05 февраля 2011

Я столкнулся с той же проблемой, я поделюсь своим решением.

Сначала вам понадобится ссылка на Nav Controller на панели вкладок в nib-файле, убедитесь, что вы подключили его.

IBOutlet UINavigationController *navigationController;

Затем получите контроллер в соответствии с рекомендациями в документации по поддержке и отправьте его управляемогоObjectContext:

SavedTableViewController *saved = (SavedTableViewController *)[navigationController topViewController];
saved.managedObjectContext = self.managedObjectContext;

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

1 голос
/ 15 января 2010

Хорошо, я смотрел долго и упорно на применении CoreDataBooks образца и сделал это так:

  • Создание IBOutlets для RootViewController (контроллер верхнего вида UINavigationController) и MapViewController (пользовательский контроллер представления) в делегате приложения.
  • Подключил выходы к контроллерам представления в MainWindow.xib
  • Добавлен следующий код для applicationDidFinishLaunching:

    // pass the managed object context to the view controllers
    RootViewController *rootViewController = (RootViewController *)[navigationController topViewController];
    rootViewController.managedObjectContext = self.managedObjectContext;
    
    mapViewController.managedObjectContext = self.managedObjectContext;
    

А теперь это работает как шарм.

0 голосов
/ 13 ноября 2015

Просто переберите каждый viewController, проверьте, есть ли у него свойство managedObjectContext, а затем установите его, если это так. Это самый чистый способ найти это.

UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
for (id viewController in [tabBarController viewControllers]) {
    if ([viewController respondsToSelector:@selector(setManagedObjectContext:)]) {
        [viewController setManagedObjectContext:self.managedObjectContext];
    }
}
0 голосов
/ 22 декабря 2012

В моем случае у меня есть rootViewController, а затем у меня есть TabBarController, поэтому при подготовке tabBarController я установил его делегат:

if ([[segue identifier]isEqualToString:@"initialTabBar"]) [(UITabBarController *)[segue destinationViewController] setDelegate:self]; } `

Я добавляю протокол к tabBarDelegate в моем RootViewController (я назвал MainViewController):

@interface MainViewController ()<UITabBarControllerDelegate>

И, наконец, в методе делегата:

-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{

Я установил свойство, но ранее я убедился, что viewcontroller имеет правильное свойство:

-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{

    if ([viewController respondsToSelector:@selector(managedContextObject)]) {
    [viewController setValue:self.managedObjectContext forKey:@"managedContextObject"];
    }
}

Таким образом, если на какой-либо вкладке viewController не используется managedContextObject, я просто не создаю свойство в его .h

Надеюсь, это будет полезно.

0 голосов
/ 21 ноября 2010

Здравствуйте, я знаю, что это старая ветка, но у меня также возникают проблемы с поиском наилучшего способа обмена MOC между TABS - хотелось бы, чтобы ссылка Маркуса Зарры на эту тему была еще активной. Маркус совершенно потрясающий, делает данные крутыми.

Это мое текущее решение в приложении didFinishLaunching:

NSArray *viewControllers = [tabBarController viewControllers];
    NSManagedObjectContext *context = self.managedObjectContext;
    for (id viewController in viewControllers) {
        [viewController setManagedObjectContext:context];

}
0 голосов
/ 24 марта 2010

Использование Xcode 3.2.1 и таргетинга 3.1.3 У меня были бесконечные проблемы с

rootViewController.managedObjectContext = self.managedObjectContext;

подход, который описывает mvexcel (и что он используется во всех примерах приложений), однако использует точно такой же подход, но формулирует его так:

[rootViewController setManagedObjectContext:self.managedObjectContext];

отлично работает.

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

0 голосов
/ 15 января 2010

Более простое решение - сделать ManagedObjectContext публичным свойством делегата приложения, чтобы везде, где вам нужен доступ, вы делали следующее:

[[[UIApplication sharedApplication] delegate] sharedManagedObjectContext];

при условии, что sharedManagedObjectContext является именем свойства.

...