AppDelegate 在启动时最后实例化

AppDelegate instantiated last on launch

我很擅长编写 iOS 应用程序,但 OS X 意外地看起来有些陌生。

这是前面的问题(继续阅读上下文):

当我的应用程序使用我的应用程序目标部署信息下主界面字段中设置的 .xib 启动时,为什么 AppDelegate 在 ViewControllers 之后实例化?


上下文(无双关语意):

我问的原因是因为我使用的是 Core Data(请原谅我对这个决定的质疑),而且通常您会在 AppDelegate 中保留指向 MOC(托管对象上下文)的指针。我的一个控制器正在尝试获取此 MOC 实例变量,但 AppDelegate 实例尚未出现,因此我的应用程序不会在启动后立即显示数据。

AppDelegate 和两个 ViewControllers 在 .xib 中。 VC 挂钩到拆分视图内的视图。他们试图在 viewDidLoad 中使用 MOC 进行查询。他们正在像这样访问 AppDelegate:

let delegate = NSApplication.sharedApplication().delegate as AppDelegate
let moc = delegate.managedObjectContext

这将崩溃,因为 .delegate 属性 的 sharedApplication() returns 为零。

我尝试从 applicationDidFinishLaunching 中的 .xib 创建一个 NSWindowController 并从 Main Interface 字段中删除 .xib,但是 applicationDidFinishLaunching 根本没有被调用。

我已确保 IB 中从应用程序和文件所有者 (NSApplcation) 委托 IBOutlets 到 AppDelegate 的所有连接都已建立。




更新 - 2015 年 3 月 31 日

Stephen Darlington 在下面的回答为 my/this 案例提供了一个很好的解决方案。据我了解,按照他建议的方式设置 MOC 实际上更好。

如果收到正确答案来解释为什么 AppDelegate 在启动过程的稍后时间被实例化,我会将其标记为正确而不是 Stephen 的。谢谢斯蒂芬!

"easy" 解决方案是让 managedObjectContext 创建一个 MOC(如果不存在)(即将其从 属性 更改为方法)。这样,无论代码先到达那里,堆栈都可用。

(我将省略有关在应用程序委托中创建核心数据堆栈和访问应用程序委托的讲座!)

我在设置 Parse 时也遇到了这个问题。为了解决这个问题,我简单地将 NSApplication 子类化并将其设置为 Info.plist 中的 Principle class。在您的 NSApplication 子类中,覆盖 init 方法并初始化 Parse 或您需要的任何其他东西。

这是另一个选项无需 NSApplication 的子类:

  • 不要将视图控制器放在您设置为主界面的.xib 中,只需将主菜单(菜单栏)、AppDelegate 和字体管理器放在那里。
  • 然后在其他 .xib 文件中创建您的视图控制器。
  • 然后在 applicationDidFinishLaunching 方法中从它们的 .xib 文件初始化视图控制器。