14

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

该应用程序使用核心数据,堆栈在应用程序委托中初始化(按照约定)。

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

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

我意识到我需要传播一个指向在应用程序委托中创建的 ManagedObjectContext 的指针,但我不知道如何继续(即使在此处此处阅读有关该主题的所有好的评论):

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

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

4

9 回答 9

14

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

在选项卡视图设计中没有什么不同。您的 AppDelegate 将 传递NSManagedObjectContext给负责创建UIViewController进入UITabBarController. 反过来,创建者在构建实例时将相关信息(NSManagedObjectNSFetchedResultsController和/或NSManagedObject实例)传递给UIViewController实例。

于 2010-01-15T17:07:23.497 回答
11

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

for (id vc in tabBarController.viewControllers) {
    [vc setManagedObjectContext:self.managedObjectContext];
}
于 2010-01-15T11:57:06.920 回答
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;
    

现在它就像一个魅力。

于 2010-01-15T10:58:40.927 回答
1

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

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

IBOutlet UINavigationController *navigationController;

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

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

Alex(来自另一篇文章)是对的,“您通常应该远离从应用程序委托获取共享对象。它使它的行为过于像一个全局变量,并且与之相关的问题一团糟。”

于 2011-02-05T16:18:05.353 回答
0

使用 Xcode 3.2.1 并以 3.1.3 为目标,我遇到了无穷无尽的问题

rootViewController.managedObjectContext = self.managedObjectContext;

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

[rootViewController setManagedObjectContext:self.managedObjectContext];

完美运行。

我也遇到了很多问题,即界面构建器无法与 Xcode 正确同步,因此无法连接插座以传递上下文。希望下一个版本能解决这一切。

于 2010-03-24T03:22:55.437 回答
0

您好,我知道这是一个旧线程,但我也无法找到处理在 TABS 之间共享 MOC 的最佳方法 - 希望 Marcus Zarra 关于该主题的链接仍然有效。马库斯完全震撼,让数据变得很酷。

这是我当前在应用程序 didFinishLaunching 中的解决方案:

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

}
于 2010-11-21T18:56:10.590 回答
0

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

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

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

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

我希望这会有所帮助。

于 2012-12-22T18:30:23.217 回答
0

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

UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
for (id viewController in [tabBarController viewControllers]) {
    if ([viewController respondsToSelector:@selector(setManagedObjectContext:)]) {
        [viewController setManagedObjectContext:self.managedObjectContext];
    }
}
于 2015-11-13T04:02:16.570 回答
-1

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

[[[UIApplication sharedApplication] delegate] sharedManagedObjectContext];

假设sharedManagedObjectContext是属性名称。

于 2010-01-15T09:48:17.167 回答