2

我正在创建我的第一个基于 NSDocument 的应用程序。我能够从头开始和通过导入旧文件来创建新文档。

这个应用程序将允许每个文档有多个窗口,因此我将覆盖 makeWindowControllers。这个方法目前很简单:

- (void) makeWindowControllers
{
    if (documentDatabase == nil) return;
    DataSheetWindowController * dswc = [[DataSheetWindowController alloc] initWithDatabase:documentDatabase];
    [self addWindowController: dswc];
}

该窗口按预期显示,但是,“保存”、“恢复到保存”和其他启用文档的菜单被禁用,就好像该文档不在响应者链中一样。

作为一个实验,我尝试将此方法添加到我的 NSWindowController 类中:

- (void)saveDocument:(id)sender {
    [[self document] saveDocument:sender];
}

使用这个方法,Save 菜单项被启用,并且选择它会导致文档的保存方法被调用。

通过阅读有关 Stack Overflow 的文档和其他问题,很明显出了点问题——我不应该将此方法放在 NSWindowController 类中。我确定我忽略了一些愚蠢的事情,但是对于我的生活,我无法弄清楚它是什么,或者在此处或网络上的其他地方提到此问题的任何其他内容。

一些可能有用的附加信息——在 IB 中,窗口的所有者和委托被设置为 NSWindowController。我创建了一个方法来显示响应者链(请参阅如何检查响应者链?)并且该文档未列出。这是响应者链的输出(但是,由于 NSDocument 不是 NSResponder 的子类,我不确定它是否应该被列出)。

RESPONDER CHAIN:
<NSClipView: 0x102344350>
<NSScrollView: 0x102344480>
<NSView: 0x102345040>
<NSWindow: 0x10234e090>

由于我放入 NSWindowController 类的 saveDocument 方法确实有效,这表明窗口控制器确实知道它与文档相关联。

那么 - 关于为什么文档表现得好像它不在响应者链中的任何想法?

更新信息:设置新文档后, initWithType 方法包含此临时行以确保文档状态已编辑:

[self updateChangeCount:NSChangeDone];

我已经验证 isDocumentEdited 返回 true。

4

1 回答 1

3

我将建议解决方案是此处指出的解决方案:

https://stackoverflow.com/a/9349636/341994

在包含窗口控制器将加载的窗口的 nib 中,文件所有者代理需要属于窗口控制器的类(选择文件所有者代理并检查身份检查器以确认/配置),并且其窗口出口必须是连接到窗口并且窗口的代理出口必须连接到文件所有者代理(选择文件所有者代理并检查连接检查器以确认)。

于 2013-08-20T03:47:18.410 回答