将 ManagedObjectContext 传递/注入到视图控制器中

Posted

技术标签:

【中文标题】将 ManagedObjectContext 传递/注入到视图控制器中【英文标题】:Passing/Inject ManagedObjectContext into view controllers 【发布时间】:2014-06-28 13:49:41 【问题描述】:

我试图通过将我的 MOC 传递给需要它们的视图控制器来做正确的事情。我正在使用第三方库来创建侧边/导航菜单,但我无法弄清楚如何将我的 MOC 从 SideController 通过到我的 ViewController 中来完成这项工作。

从这个(简单的部分)第 1 步开始:

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

    LoginViewController *rootView = (LoginViewController *) self.window.rootViewController;
    rootView.managedObjectContext = self.managedObjectContext;

然后在我的用户登录后,我将它传递给第三方控制器(这里仍然可以)第 2 步:

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
    NSString *segueIdentifier = [segue identifier];
    if ([segueIdentifier isEqualToString:@"LoginSegue"]) 
        TheRootViewController *rootViewController = [segue destinationViewController];
        rootViewController.managedObjectContext = self.managedObjectContext;
    

这里是第三部分代码Step 3:

- (void)awakeFromNib


...
    MyNavigationController *navigationController = [self.storyboard instantiateViewControllerWithIdentifier:@"contentViewController"];
    navigationController.managedObjectContext = _managedObjectContext;
    self.contentViewController = navigationController;
...

我的问题是,步骤 3 中的代码 (awakeFromNib) 在步骤 2 中的 segue 有机会在 RootViewController 上设置 MOC 之前被调用。

基本上,我能找到的所有示例都一直使用故事板,但由于我的第三方应用程序使用代码,所以我有点混合。如何在调用 awakeFromNib 之前将 MOC 获取到 TheRootController?这还可能吗。还有其他方法吗?

我真的很早就在项目中,不想开始在 AppDelegate 中填充东西,而是努力弄清楚如何在第三方应用程序中做正确的事情。

【问题讨论】:

如果您的核心数据使用相对琐碎,我敢建议将所有核心数据堆栈包装在一个单例对象中。这种方法当然有几个弱点,但如果您有太多第三方代码需要适应,它可能适合您。 【参考方案1】:

如果您想坚持将 MOC 从控制器传递到控制器,您只需将引用 MOC 的 awakeFromNib 代码移动到 viewDidLoad 中。在 prepareForSegue 函数完成后会调用 viewDidLoad。

我还想补充一点,将 MOC 填充到 AppDelegate 中确实是个坏主意。但正如@spassas 所建议的那样,使用为您管理 MOC 的单例对象可能是个好主意。我经常在我的项目中使用一个。您可以在此要点中看到一个示例:https://gist.github.com/grantamos/1156fe4d2461dafd9d67

【讨论】:

viewDidLoad 是否只被调用一次?即在移动该代码之前我需要了解什么? 我无法通过提供的小代码 sn-p 来判断,但您应该可以将提供的代码从 awakeFromNib 移动到 viewDidLoad。如果您担心破坏某些东西,请考虑仅移动 navigationController.managedObjectContext = _managedObjectContext;到 viewDidLoad 方法,保留所有控制器的创建。 关于您的第一个问题,可以多次调用 viewDidLoad。 awakeFromNib 在视图控制器的生命周期内只调用一次。查看此 *** 帖子了解更多信息:***.com/questions/9137413/… 我不断看到我的 viewDidLoad 方法在我的 prepareForSegue 之前被调用。不知道这里发生了什么,但是当这种情况发生时,我无法正确设置 MOC。 NM 之前的评论。我的 awakeFromNib 中有布局的东西。这样做会导致 viewDidLoad 直接从 awakeFromNib 触发(在 segue 之前)。我将所有代码移至 viewDidLoad 并且效果很好。更好的是,我现在实际上正在注入 MOC,完美!【参考方案2】:

awakeFromNib 在连接到视图控制器时很早就被调用(它在故事板之外的任何人获得对该视图控制器的引用之前被调用)。您能否将awakeFromNib 中的代码移动到循环稍后调用的方法中,例如viewWillAppear:viewDidLoad?我相信这两个都是在prepareForSegue:之后调用的。

【讨论】:

以上是关于将 ManagedObjectContext 传递/注入到视图控制器中的主要内容,如果未能解决你的问题,请参考以下文章

将 ManagedObjectContext 传递/注入到视图控制器中

如果它是子视图控制器,如何将 AppDelegate 中的 managedObjectContext 传递给正确的视图控制器?

将 NSManagedObject 重新插入到 ManagedObjectContext

在核心数据的类之间传递 managedObjectContext 时出错

在没有 managedObjectContext 的视图之间传递 CoreData 对象

“Appdelegate”没有可见的@interface 声明选择器“managedObjectContext”