2

我有一个NS(Persistent)Document.

我通过 Xcode 运行我的应用程序,然后创建一个新文档(没有任何数据),然后退出我的应用程序。在这种情况下,我可以检查initandwindowControllerDidLoadNib:是否被调用

如果我用 Xcode 重新运行我的应用程序,那么之前的文档会自动打开。但是,我可以检查既不init也不windowControllerDidLoadNib:被调用。

为什么会这样?

4

1 回答 1

7

你看到的是窗户修复。正如该文档(基于文档的应用程序编程指南的一部分)所说:

文档架构在窗口恢复过程中实现了以下步骤;这些步骤与图 5-2 中所示的数字相关:

  1. NSWindowController方法setDocument:将文档窗口的恢复类设置为共享NSDocumentController对象的类。每当其NSWindow状态发生变化时,对象会通过发送invalidateRestorableState给自身而使其可恢复状态无效。
  2. 在下一个适当的时间,Cocoa 向窗口发送一条encodeRestorableStateWithCoder:消息,窗口将标识和状态信息编码到传入的编码器中。
  3. 当系统重新启动时,Cocoa 重新启动应用程序并将restoreWindowWithIdentifier:state:completionHandler:消息发送到NSApp对象。

    应用程序可以重写此方法来执行窗口恢复所需的任何常规工作,例如替换新的恢复类或从单独的包中加载它。

    NSApp解码窗口的恢复类,将消息restoreWindowWithIdentifier:state:completionHandler:发送到恢复类对象 [在本例中,文档控制器的类 — Peter],然后返回YES.

  4. 恢复类重新打开文档并找到它的窗口。然后它以窗口为参数调用传入的完成处理程序。
  5. Cocoa 将消息restoreStateWithCoder:发送到窗口,窗口从传入的对象中解码其可恢复状态NSCoder并恢复其内容的详细信息。

[图 5-2,以及一段解释视图、其他响应者和文档也被保存和恢复的段落]

当应用程序重新启动时,CocoarestoreStateWithCoder:依次将消息发送给相关对象:首先发送给NSApplication对象,然后发送给每个NSWindow对象,然后发送给NSWindowController对象,然后发送给NSDocument对象,然后发送给每个保存状态的视图。

窗口恢复协议也用于与文档无关的窗口,但文档机制会为您处理大部分脏活。如果您需要在窗口恢复的任何一侧(可能是两侧)执行任何操作,请覆盖encodeRestorableStateWithCoder:restoreStateWithCoder:在您的文档中。前者是您保存临时信息(如选择)的地方,后者是您在复活的文档及其窗口中恢复该信息的地方。

编码器的存在意味着文档是使用initWithCoder:而不是初始化的init,尽管这不是您应该依赖的记录事实(在窗口恢复的上下文中)。

于 2013-05-03T14:35:15.020 回答