如何将managedObjectContext从appDelegate传递到第一个ViewController,当它们是两个视图之间的导航控制器时

时间:2012-03-17 04:45:14

标签: ios delegates uinavigationcontroller storyboard moc

我在研究和试图弄清楚如何解决以下问题时,已经在键盘上击打了3天以上。

我有一个看起来像这样的故事板:

初始应用启动箭头 - >到导航控制器 - >到主视图控制器。

我的appDelegate正在创建managedObjectContext并且它用数据填充一些实体(仅用于测试目的,一旦我准备好与外部源集成,它将被删除)。这工作很好。现在我的问题是我不知道我如何将MOC从appDelegate传递到我的第一个ViewController,因为导航控制器挡住了。我在appDidFinish方法中的当前代码如下所示:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    // Pass the managed object context to the root view controller
    MainMenuViewController *rootView = (MainMenuViewController *)self.window.rootViewController;
    rootView.managedObjectContext = self.managedObjectContext; 

    //My actual Core data setup and adding data to it, it works I've tested it.

    return YES;
     }

现在,当我将故事板中的应用程序启动箭头更改为指向我的mainMenuViewController时,我的代码可以正常工作,但是我在所有视图中都丢失了导航栏。我也知道如何通过- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender将MOC从我的mainMenu传递到另一个视图,但我似乎无法弄清楚如何从appDelegate到MainViewController的初始传递,因为darn导航控制器是介于两者之间。

我已经在这个网站上搜索了很多线程(和其他人),我只找到了“Tabbed应用程序”的解决方案,其他人希望我序列化该对象,但出于我的目的,我不能这样做。 (只有少数视图会收到MOC,而其他视图会传递一个视图创建和修改的数据,以便在独特视图中为特定目的进行定制)

非常感谢iOS和Objective-C对此nub的任何帮助。提前谢谢。

编辑:我得到的错误是“由于未捕获的异常终止应用程序... [UINavigationController setManagedObjectContext]无法识别的选择器发送到实例...

3 个答案:

答案 0 :(得分:10)

如果您从Xcode 4.3中的“Master-Detail”应用程序模板创建一个新应用程序(我认为也是4.2),选中“使用故事板”和“使用核心数据”选项,您会发现AppDelegate.m中的以下内容:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
    MasterViewController *controller = (MasterViewController *)navigationController.topViewController;
    controller.managedObjectContext = self.managedObjectContext;
    return YES;
}

这似乎正是您正在寻找的。关键是您可以在导航控制器中查询其视图控制器。

答案 1 :(得分:2)

如果在AppDelegate中设置了NSManagedObjectContext,则不传递它;相反,你创建了它的引用:

AppDelegate *appDel = [UIApplication sharedApplication].delegate;   
NSManagedObjectContext *context = appDel.managedObjectContext;

您引用它的对象类型与接收对象和AppDelegate之间的任何其他类型的对象无关。

答案 2 :(得分:0)

除了我的第一个答案,它与接受的答案基本相同 - 除了使用我的答案,您可以使用或不使用任何模板(而不仅仅是拆分视图模板)-I' m提供一个更直接回答您的问题的答案,这就是如何将对上下文管理器对象的引用传递给segue之后的目标视图控制器。

这个答案,就像我的第一个答案(与接受的答案不同),假设您至少知道应用程序中托管对象上下文的位置,并且您具有创建引用所需的基本技能(不同于接受的答案,假设您不能在Xcode中使用Find ...,也不记得如何为指针赋值,例如:

id moc = [reference to the managed object context object that you can find]

由于您似乎对涉及模板的答案做出了更好的响应,请尝试单应用程序视图模板中UIViewController子类中提供的prepareForSegue方法覆盖。在内部,你会注意到Apple留下的一些评论。

简而言之,您将创建对目标视图控制器的引用,如下所示:

SecondVC *vc2 = segue.destinationController;

然后,将目标视图控制器中托管对象上下文变量的指针引用值设置为创建实例的引用点的值:

vc2.mbo = AppDelegate.mbo;

我提供了一个非常详尽的示例(带有视频演示),可以在以下位置创建没有故事板的segue(即以编程方式):

Set segue identifier programmatically

顺便说一下,如果您在我的回答中理解AppDelegate参考的使用有困难,我将解释它:

  1. 只要您使用任何Xcode模板创建新项目,Apple就会在AppDelegate.h / .m中放置其Core Data托管对象上下文引用,并在模板设置期间选中Use Code Data复选框。要在整个应用程序中使用该引用(即,在其他.m文件中,因此您不会广告创建它的多个实例),您将创建对AppDelegate的全局应用程序范围的引用 - 恰好是一个委托UIApplication是一个单例,它也使AppDelegate成为单例,只需将它添加到您打算引用托管对象上下文的每个实现文件中:

    import" AppDelegate.h"

    定义AppDelegate((AppDelegate *)[[UIApplication sharedApplication]委托])

  2. 现在,您可以在添加这两行的任何位置访问托管对象上下文对象:

    [AppDelegate.mbo...];