3

我知道如何解决问题,但令我困扰的是我不明白为什么这不起作用。我有一个使用 Core Data 的 UIViewController 子类,所以它需要 NSManagedObjectContext。该控制器是从一个 nib 文件中加载的,该文件位于标签控制器内的导航控制器下。

我尝试在 initWithCoder 和 viewDidLoad 中执行此操作,但由于某种原因它不起作用:

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

出于某种原因,managedObjectContext 返回 nil,当我稍后尝试创建托管对象时我得到了这个:

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

当您的上下文为零或模型无法加载(或确实缺少实体)时,您会得到什么。

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

如果我按照食谱示例应用程序所做的那样做:

- (void)applicationDidFinishLaunching:(UIApplication *)application {

    loggingViewController.managedObjectContext = self.managedObjectContext;

    // Standard stuff
    [window addSubview:tabBarController.view];
    [window makeKeyAndVisible];
}

(loggingViewController 是应用程序委托中的 IBOutlet)。

有谁知道这里具体可能发生什么?如果“过早”完成,它似乎会失败,但尤其是对于 viewDidLoad 我希望它能够工作,因为我认为在调用 addSubview 之后会发生这种情况。

4

1 回答 1

6

完全按照食谱应用程序的功能进行操作。

如果您在 initWithCoder 中尝试,您不知道应用程序委托是否已完成初始化(尚未完成)

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

这就是为什么您应该像这样访问应用程序委托的原因:

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

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

因为从应用程序委托中,您确切地知道已经执行了哪些初始化,并且可以在适当的时间传递上下文。


更新:

问题是您的 View Controller 实例可能在 Mainwindow.xib 中被实例化。在应用程序委托收到 UIApplicationDidFinishLaunchingNotification 通知之前,Mainwindow.xib(以及它引用的任何其他 nib)被“解冻”。

无法保证物体从笔尖解冻的顺序。在视图控制器上调用 initWithCoder: 时,您不知道还有哪些其他对象已从 nib 中解冻。您也无法确定应用委托是否已收到 UIApplicationDidFinishLaunchingNotification 通知。

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

最好让应用程序委托在“良好且准备就绪”时在上下文中传递,最好是在 applicationDidFinishLaunching: 方法中。

希望更清楚一点,你应该看看iphone编程指南:http: //developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/index.html

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

希望有帮助。


另一个更新:

深入讨论iphone启动顺序: http ://www.bit-101.com/blog/?p=2159

于 2010-01-07T18:13:06.890 回答