如何在不编码窗口状态的情况下以编程方式终止 NSApp?
Posted
技术标签:
【中文标题】如何在不编码窗口状态的情况下以编程方式终止 NSApp?【英文标题】:How to programmatically terminate NSApp without encoding window state? 【发布时间】:2016-06-12 23:39:17 【问题描述】:所有支持NSWindowRestoration
的 OS X 应用程序都可以通过选择菜单项“退出并关闭所有窗口”(Option-Command Q)来关闭。这将禁用状态恢复,并且下次打开应用程序时所有窗口都将处于默认位置。
菜单项触发NSApplication
上的terminate:
方法。但是常规的“关闭应用程序”菜单也是如此(命令 Q)。
如何以编程方式执行“退出并关闭所有窗口”?我真的必须自己关闭所有窗口然后调用terminate:
吗?
当两个操作都连接到同一个terminate:
方法时,Apple 如何神奇地决定要做什么?
【问题讨论】:
你为什么不直接在终止窗口时循环并关闭它们? @l'L'l 因为这将是额外的代码来管理,而 Apple 有一个使用简单方法调用的解决方案。 【参考方案1】:似乎没有一个很好的方法来做到这一点。您可能想向 Apple 提交错误请求(并说明您需要它的原因)。
当两个操作都连接到同一个
terminate:
方法时,Apple 如何神奇地决定要做什么?
好吧,看看 AppKit 的反汇编,-[NSApplication terminate:]
似乎检查了发件人是否是NSMenuItem
的实例。如果是,则检查其userInterfaceItemIdentifier
是否等于@"NSAlternateQuitMenuItem"
。
我想,您可以使用该标识符创建一个虚拟菜单项,并将其作为发送者传递给 -terminate:
,尽管由于这依赖于实现细节,它可能随时中断。
另一个控制因素是系统偏好设置>常规>“退出应用程序时关闭窗口”的设置。这对应于用户默认键NSAlternateQuitMenuItem
,尽管这又是一个实现细节。看来您可以在调用-terminate:
之前设置它,然后在-applicationWillTerminate:
委托方法中删除该设置。 (您的更改将与您的应用程序相关联。它们不会影响其他应用程序或系统偏好设置中的设置。)当然,您必须确保禁用突然终止以获取该委托方法调用。
【讨论】:
我不知道,NSMenuItem 上有一个userInterfaceItemIdentifier
属性。我刚刚在 Objective-C 中创建了必要的接口定义来访问它。非常感谢!
提出了一些进一步的调查,这是唯一获得此类标识符的菜单项。它最初不存在,但在应用启动一段时间后自动添加。
整个菜单项“最初”并不存在。它是由 Cocoa 在设置主菜单时创建的。如果您要依赖此具有特定标识符的菜单项,那就太糟糕了。绝对不要依赖它是唯一具有标识符的项目。
当然,我只是想确保不再有我可能错过的魔法。我目前只本地化应用程序的菜单,有趣的是,甚至“显示工具栏”和“隐藏工具栏”之间的自动文本替换也依赖于 Apple 为每种语言选择的完全相同的措辞。以上是关于如何在不编码窗口状态的情况下以编程方式终止 NSApp?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用 UINavigationController 的情况下以编程方式进入 rootViewController
如何在不“连接”它们的情况下以编程方式访问 NIB 中的 UI 元素?
如何在不使用命令的情况下以编程方式关闭/重启 linux 机器(运行时)
如何在不使用外部主机的情况下以编程方式查找设备的外部 IP 地址?