【问题标题】:How to programmatically terminate NSApp without encoding window state?如何在不编码窗口状态的情况下以编程方式终止 NSApp?
【发布时间】:2016-06-12 23:39:17
【问题描述】:

所有支持NSWindowRestoration 的 OS X 应用程序都可以通过选择菜单项“退出并关闭所有窗口”(Option-Command Q)来关闭。这将禁用状态恢复,并且下次打开应用程序时所有窗口都将处于默认位置。

菜单项触发NSApplication 上的terminate: 方法。但是常规的“关闭应用程序”菜单也是如此(命令 Q)。

如何以编程方式执行“退出并关闭所有窗口”?我真的必须自己关闭所有窗口然后调用terminate:吗?

当两个操作都连接到同一个terminate: 方法时,Apple 如何神奇地决定要做什么?

【问题讨论】:

  • 你为什么不直接在终止窗口时循环并关闭它们?
  • @l'L'l 因为这将是额外的代码来管理,而 Apple 有一个使用简单方法调用的解决方案。

标签: macos state-restoration nswindowrestoration


【解决方案1】:

似乎没有一个很好的方法来做到这一点。您可能想向 Apple 提交错误请求(并说明您需要它的原因)。

当两个操作都连接到同一个terminate: 方法时,Apple 如何神奇地决定要做什么?

好吧,看看 AppKit 的反汇编,-[NSApplication terminate:] 似乎检查了发件人是否是NSMenuItem 的实例。如果是,则检查其userInterfaceItemIdentifier 是否等于@"NSAlternateQuitMenuItem"

我想,您可以使用该标识符创建一个虚拟菜单项,并将其作为发送者传递给 -terminate:,尽管由于这依赖于实现细节,它可能随时中断。

另一个控制因素是系统偏好设置>常规>“退出应用程序时关闭窗口”的设置。这对应于用户默认键NSAlternateQuitMenuItem,尽管这又是一个实现细节。看来您可以在调用-terminate: 之前设置它,然后在-applicationWillTerminate: 委托方法中删除该设置。 (您的更改将与您的应用程序相关联。它们不会影响其他应用程序或系统偏好设置中的设置。)当然,您必须确保禁用突然终止以获取该委托方法调用。

【讨论】:

  • 我不知道,NSMenuItem 上有一个userInterfaceItemIdentifier 属性。我刚刚在 Objective-C 中创建了必要的接口定义来访问它。非常感谢!
  • 提出了一些进一步的调查,这是唯一获得此类标识符的菜单项。它最初不存在,但在应用启动一段时间后自动添加。
  • 整个菜单项“最初”并不存在。它是由 Cocoa 在设置主菜单时创建的。如果您要依赖此具有特定标识符的菜单项,那就太糟糕了。绝对不要依赖它是唯一具有标识符的项目。
  • 当然,我只是想确保不再有我可能错过的魔法。我目前只本地化应用程序的菜单,有趣的是,甚至“显示工具栏”和“隐藏工具栏”之间的自动文本替换也依赖于 Apple 为每种语言选择的完全相同的措辞。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-19
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多