You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 13:02:33