如何在使用UITabBarController时共享ManagedObjectContext

时间:2010-01-15 09:34:50

标签: iphone cocoa-touch core-data uitabbarcontroller cocoa-design-patterns

我有一个iPhone应用程序,它有一个MainWindow.xib,上面有一个UITabBarController,它在ViewControllers数组中有一个UINavigationController和一个自定义的UIViewController子类。 UINavigationController和自定义视图控制器的根视图控制器都是从其他xib文件加载的。

应用程序使用核心数据,堆栈在应用程序委托中初始化(根据the convention)。

app委托将UITabBarController添加到窗口:

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

我意识到我需要传播指向应用委托中创建的ManagedObjectContext的指针,但我不知道如何继续(甚至阅读有关主题here和{{3}的所有好评。 }):

  • 我是否将ManagedObjectContext传播到UITabBarController并从那里传播到各个视图控制器,如果是,如何?
  • 或者我将ManagedObjectContext直接传播到UINavigationController的根视图控制器和自定义视图控制器,我该怎么做?

我想我不太了解如何使用UITabBarController。

9 个答案:

答案 0 :(得分:14)

理想情况下,您希望将NSManagedObjectContextNSFetchedResultsController或相关的NSManagedObject“向下”传递到UIViewController。这允许“父母”控制“孩子”并确定孩子应该拥有什么。这会创建一个更松散耦合的设计,并允许您根据需要轻松重新排列UIViewController个实例。它还可以更轻松地重用UIViewController

在标签视图设计中,它没有什么不同。您的AppDelegate将NSManagedObjectContext传递给负责创建进入UIViewController的初始UITabBarController实例的人员。反过来,创建者会在构建它们时将相关信息(NSManagedObjectNSFetchedResultsController和/或NSManagedObject个实例)传递到UIViewController个实例中。

答案 1 :(得分:11)

如果要使用依赖注入方法通过标签栏控制器传递托管对象上下文,更强大的解决方案是在applicationDidFinishLaunching中循环所有视图控制器:

for (id vc in tabBarController.viewControllers) {
    [vc setManagedObjectContext:self.managedObjectContext];
}

答案 2 :(得分:1)

很好,我在CoreDataBooks示例应用程序中看起来很长很难,并且这样做了:

  • 在应用程序委托中为RootViewController(UINavigationController的顶视图控制器)和MapViewController(自定义视图控制器)创建了IBOutlets。
  • 将插座连接到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;
    

现在它就像一个魅力。

答案 3 :(得分:1)

我遇到了同样的问题,我会分享我的解决方案。

首先,你需要在nib文件的Tab栏中引用Nav Controller,确保你连接它。

IBOutlet UINavigationController *navigationController;

然后,按照支持文档中的建议获取Controller,并将其发送到managedObjectContext:

SavedTableViewController *saved = (SavedTableViewController *)[navigationController topViewController];
saved.managedObjectContext = self.managedObjectContext;
Alex(来自另一篇文章)是对的,“你通常应该避免从app委托中获取共享对象。它使得它的行为太像一个全局变量,并且它有一大堆与之相关的问题。 “

答案 4 :(得分:0)

使用Xcode 3.2.1并定位3.1.3我对

有无穷无尽的问题
rootViewController.managedObjectContext = self.managedObjectContext;

mvexcel描述的方法(并且它在整个示例应用程序中都被使用),但是使用完全相同的方法,但将其描述为:

[rootViewController setManagedObjectContext:self.managedObjectContext];

完美无缺。

我也遇到了很多问题,界面构建器没有与Xcode正确同步,因此无法连接出口以传递上下文。希望下一个版本修复所有这些。

答案 5 :(得分:0)

您好我知道这是一个老线程,但我也遇到了在TABS之间寻找共享MOC的最佳方法的问题 - 希望Marcus Zarra关于该主题的链接仍然活跃。马库斯完全晃动,让数据变得很酷。

这是我目前在申请中的解决方案didFinishLaunching:

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

}

答案 6 :(得分:0)

在我的情况下,我有一个rootViewController然后我有一个TabBarController,所以在segue准备tabBarController时我设置了它的委托:

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

我将协议添加到我的RootViewController中的tabBarDelegate(我称之为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

中创建属性。

我希望这会有所帮助。

答案 7 :(得分:0)

只需遍历每个viewController,检查它是否具有managedObjectContext属性,然后再设置它。这是我能找到的最干净的方式。

UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
for (id viewController in [tabBarController viewControllers]) {
    if ([viewController respondsToSelector:@selector(setManagedObjectContext:)]) {
        [viewController setManagedObjectContext:self.managedObjectContext];
    }
}

答案 8 :(得分:-1)

更直接的解决方案是让ManagedObjectContext成为您的app delegate的公共属性,因此无论您何时需要访问它,您都可以执行以下操作:

[[[UIApplication sharedApplication] delegate] sharedManagedObjectContext];

假设 sharedManagedObjectContext 是属性名称。