Cocoa &引用;beginModalSessionForWindow“;结果是非模态会话?

Cocoa &引用;beginModalSessionForWindow“;结果是非模态会话?,cocoa,modal-dialog,Cocoa,Modal Dialog,我正在构建一个应用程序,其中包含一个主窗口和一个子窗口,我希望以模式会话的形式呈现。因此,我在窗口控制器中使用以下代码: self.session = [[NSApplication sharedApplication] beginModalSessionForWindow: self.window]; [[NSApplication sharedApplication] runModalSession: self.session]; 然而,不管我把这段代码放在哪里——在windowDidLo

我正在构建一个应用程序,其中包含一个主窗口和一个子窗口,我希望以模式会话的形式呈现。因此,我在窗口控制器中使用以下代码:

self.session = [[NSApplication sharedApplication] beginModalSessionForWindow: self.window];
[[NSApplication sharedApplication] runModalSession: self.session];
然而,不管我把这段代码放在哪里——在windowDidLoad中,在主窗口的post windowDidLoad调用中,甚至在窗口控制器的init函数中——我得到的都是一个无模式子窗口。子窗口显示在主窗口上方,但主窗口继续响应输入事件


我做错了什么?

nvm-通过阅读一些示例找到了我的答案。(再一次,在发布到Stack之前数小时的研究并没有得出答案,而我在发布之后就偶然发现了一些见解。)

对于后代来说,答案是:beginModalSessionForWindow的工作方式与runModalForWindow不同

使用runModal,您可以在任何地方执行该代码,Cocoa将立即停止除模式窗口之外的所有处理。(不幸的是,这包括绑定到后台处理的非UI事件的计时器。)执行runModal的代码被阻止,并且只有在模式窗口关闭后才能恢复。系统强制执行窗口的模态

beginModalSessionForWindow的工作原理非常不同。无论在何处执行,代码都会启动模态窗口,然后继续执行。在一般用例中(如Apple的示例所示),如果在循环之前调用beginModal,然后在轮询会话状态时对循环进行调节,则循环可以执行您想要的任何其他处理;在循环过程中,它也会阻止正常的UI事件——就像任何iAction在执行长时间运行的循环时所做的那样

关键是beginModalSession实际上并不强制执行窗口的任何模式。相反,您的代码通过执行长时间运行的循环来强制执行窗口的模态。如果不使用循环,而是让“模态”会话运行并恢复普通事件循环。。。然后,您的其他窗口将获得所有事件处理,包括UI事件。“模态”窗口变为非模态


我认为“beginModalSessionForWindow”实际上应该称为BeginModelsSessionForWindow,因为它就是这样做的:它创建一个无模式窗口并返回。

不,它不创建无模式窗口。窗口模式和应用程序模式行为之间存在区别。工作表是窗口模式,这意味着它可以阻止您在承载工作表的窗口中执行任何其他操作,但不会阻止您在应用程序的其他位置工作。是的,我知道工作表是窗口模式-但我的评论是关于窗口的,而不是工作表。调用beginModalSessionForWindow会创建一个窗口,并且不会阻止窗口或应用程序的任何方面。
runModalSession:
上的文档比
beginModalSessionForWindow:
上的文档更好地描述了它的工作原理。