代码之家  ›  专栏  ›  技术社区  ›  Nimrod

当我试图在这些点进行核心数据初始化时,为什么会失败?

  •  3
  • Nimrod  · 技术社区  · 16 年前

    我知道如何解决这个问题,但我不明白为什么这不起作用,这让我很困扰。我有一个使用核心数据的UIViewController子类,因此它需要NSManagedObjectContext。控制器从nib文件加载,该文件位于选项卡控制器内的导航控制器下。

    MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
    self.managedObjectContext = [[appDelegate managedObjectContext] retain];
    

    出于某些原因,managedObjectContext返回nil,当我稍后尝试创建托管对象时,会得到以下结果:

    ***由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“+entityForName:在此模型中找不到名为“LogRecord”的实体。”

    当您的上下文为nil或模型无法加载(或确实缺少实体)时,您会得到这样的结果。

    如果我在saveLogEntry方法(创建托管对象并保存上下文)的顶部执行完全相同的操作,那么它就可以正常工作。

    - (void)applicationDidFinishLaunching:(UIApplication *)application {
    
        loggingViewController.managedObjectContext = self.managedObjectContext;
    
        // Standard stuff
        [window addSubview:tabBarController.view];
        [window makeKeyAndVisible];
    }
    

    (loggingViewController是应用程序代理中的IBOutlet)。

    有人知道这里到底发生了什么吗?如果“太早”完成,它似乎会失败,但特别是对于viewDidLoad,我希望它能够工作,因为我认为这是在调用addSubview之后发生的。

    1 回复  |  直到 16 年前
        1
  •  6
  •   Corey Floyd    16 年前

    完全按照recipes应用程序所做的操作。

    如果您尝试viewDidLoad,您也会遇到类似的问题。

    这就是为什么你应该 正在访问应用程序代理,如下所示:

    MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
    self.managedObjectContext = [[appDelegate managedObjectContext] retain];
    

    这是糟糕的形式。它将耦合引入到您的设计中。使用依赖项注入,就像示例一样。它使你的应用程序更加灵活。


    更新:

    这与viewDidLoad类似。在viewDidLoad中,您可以确保nib中的所有其他对象已正确解冻和初始化,但由于应用程序委托的配置发生在nib文件之外,因此无法确定调用应用程序委托是否安全。

    当应用程序委托处于“良好且准备就绪”状态时,最好是在ApplicationIDFinishLaunching:方法中通过它。

    http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/index.html

    收集iPhone应用程序生命周期的更好解释。

    希望有帮助。


    还有一个更新:

    http://www.bit-101.com/blog/?p=2159