Iphone 使用UITabBarController时如何共享ManagedObjectContext

Iphone 使用UITabBarController时如何共享ManagedObjectContext,iphone,cocoa-touch,core-data,uitabbarcontroller,cocoa-design-patterns,Iphone,Cocoa Touch,Core Data,Uitabbarcontroller,Cocoa Design Patterns,我有一个iPhone应用程序,它有一个MainWindow.xib,其中包含一个UIAbbarController,而UIAbbarController在其ViewController数组中又有一个UINavigationController和一个自定义UIViewController子类。UINavigationController的根视图控制器和自定义视图控制器都是从其他xib文件加载的 应用程序使用核心数据,堆栈在应用程序委托中初始化(根据) 应用程序委托将UITabBarControll

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

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

应用程序委托将UITabBarController添加到窗口:

- (void)applicationDidFinishLaunching:(UIApplication *)application {        
    // Configure and show the window
    [window addSubview:[tabBarController view]];
    [window makeKeyAndVisible];
}
我意识到我需要传播一个指向在app delegate中创建的ManagedObjectContext的指针,但我不知道如何继续(甚至阅读所有关于该主题的好评论和):

  • 我是否将ManagedObjectContext传播到UITabBarController,然后再传播到各个视图控制器?如果是,如何传播
  • 或者我是否将ManagedObjectContext直接传播到UINavigationController的根视图控制器和自定义视图控制器,我将如何做到这一点

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

一个更直接的解决方案是将ManagedObjectContext设置为应用程序代理的公共属性,因此无论您在哪里需要访问它,都可以执行以下操作:

[[[UIApplication sharedApplication] delegate] sharedManagedObjectContext];

假设sharedManagedObjectContext是属性名。

很好,我仔细研究了CoreDataBooks示例应用程序,并按照如下方式操作:

  • 在应用程序委托中创建指向RootViewController(UINavigationController的俯视图控制器)和MapViewController(自定义视图控制器)的IBOutlet
  • 将插座连接到MainWindow.xib中的视图控制器
  • 将以下代码添加到
    ApplicationIDFinishLaunching

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

现在,它就像一个魅力。

如果您想使用依赖项注入方法通过选项卡栏控制器传递托管对象上下文,一个更健壮的解决方案是在
applicationdFinishLaunching
中的所有视图控制器上循环:

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

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


在选项卡视图设计中也一样。您的AppDelegate将
NSManagedObjectContext
传递给负责创建进入
UIAbbarController
的初始
UIViewController
实例的人。反过来,创建者将相关信息(
NSManagedObject
NSFetchedResultsController
、和/或
NSManagedObject
实例)传递到正在构建的
UIViewController
实例中。

使用Xcode 3.2.1和目标3.1.3,我对

rootViewController.managedObjectContext = self.managedObjectContext;
mvexcel描述的方法(在所有示例应用程序中都使用),但使用完全相同的方法,但措辞如下:

[rootViewController setManagedObjectContext:self.managedObjectContext];
工作完美


我还遇到了很多问题,界面生成器没有与Xcode正确同步,因此无法连接出口来传递上下文。希望下一个版本能解决所有问题。

您好,我知道这是一个旧线程,但我也在寻找处理标签间共享MOC的最佳方法时遇到问题-希望Marcus Zarra关于该主题的链接仍然处于活动状态。马库斯完全摇滚,让数据更酷

这是我当前在application didFinishLaunching中的解决方案:

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

}

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

首先,您需要在nib文件的选项卡栏中引用Nav控制器,确保将其连接起来

IBOutlet UINavigationController *navigationController;
然后,按照支持文档中的建议获取控制器,并将其发送到managedObjectContext:

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

Alex(来自另一篇文章)是对的,“你通常应该远离从应用程序委托获取共享对象。这会使它的行为太像一个全局变量,这会带来一大堆与之相关的问题。”

在我的例子中,我有一个rootViewController,然后我有一个TabBarController,因此,在准备tabBarController的过程中,我设置了它的委托:

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

我将协议添加到我的RootViewController(我称为MainViewController)中的tabBarDelegate:

@interface MainViewController()

最后在委托方法中:

-(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中创建属性


我希望这会有帮助。

只需在每个viewController中循环,检查它是否有
managedObjectContext
属性,然后设置它。这是我能找到的最干净的方法

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

这可能行得通,我会试试,但我仍然好奇如何按照苹果在其文档中列出的设计模式来做(参见我问题中的链接)。无论如何,谢谢你的回答。这取决于你的应用程序的体系结构。你不必在你的应用程序委托中设置NSManagedObjectContext,特别是当你使用它仅限于一个视图控制器时,在这种情况下,你可以在该视图控制器中设置它。如果