如何在macOS Swift应用强制退出时执行指定操作?
处理macOS应用强制退出时的按键重映射恢复问题
首先明确:SIGKILL信号是操作系统强制终止进程的信号,任何应用都无法捕获、忽略或处理,所以不可能在应用被强制退出的瞬间执行代码。但可以通过以下替代方案实现类似效果:
1. 采用「运行时生效」的映射模式(最优解)
如果你的按键重映射是通过CGEventTap实现的系统级按键拦截:
- 这种方式的映射仅在应用进程存活时生效,一旦进程被强制终止,系统会自动移除对应的EventTap,映射会立刻失效,无需额外处理。
- 若你是通过修改系统配置文件(比如Karabiner配置、系统输入法设置等)实现重映射,建议改成动态拦截模式,避免修改持久化配置,从根源上解决退出时的恢复问题。
2. 用外部守护进程做补偿检查
编写一个轻量的launchd守护进程,定期检查主应用的存活状态,一旦发现应用已终止(包括强制退出),就执行按键重映射的恢复操作:
- 创建一个plist配置文件(放在
~/Library/LaunchAgents/目录下),设置定期执行(比如每10秒)一个脚本或小二进制程序。 - 脚本逻辑:通过
pgrep -x 应用进程名或mdls -name kMDItemCFBundleIdentifier /Applications/你的应用.app获取BundleID,检查对应进程是否存在。 - 若进程不存在,执行恢复操作(比如调用重置重映射的API、恢复配置文件等)。
3. 捕获可处理的终止信号,覆盖更多场景
虽然无法处理SIGKILL,但可以捕获SIGTERM、SIGHUP等可处理的信号(比如用户通过Cmd+Q、活动监视器的「退出」按钮终止应用的场景),在这些场景下执行恢复:
import Dispatch func setupSignalHandlers() { // 处理SIGTERM信号 let sigtermSource = DispatchSource.makeSignalSource(signal: SIGTERM, queue: .main) sigtermSource.setEventHandler { [weak self] in self?.restoreKeyRemapping() exit(0) } sigtermSource.resume() signal(SIGTERM, SIG_IGN) // 屏蔽默认信号处理 // 同理可处理SIGHUP等其他信号 let sighupSource = DispatchSource.makeSignalSource(signal: SIGHUP, queue: .main) sighupSource.setEventHandler { [weak self] in self?.restoreKeyRemapping() exit(0) } sighupSource.resume() signal(SIGHUP, SIG_IGN) } // 在App启动时调用(比如AppDelegate的applicationDidFinishLaunching方法中) func applicationDidFinishLaunching(_ aNotification: Notification) { setupSignalHandlers() // 初始化按键重映射 setupKeyRemapping() }
内容的提问来源于stack exchange,提问作者Perch Hakobyan
相关产品推荐
相关产品推荐

