为何NSWorkspace通知与监听器未接收或触发?
问题分析与修复方案
你的代码存在几个关键问题,导致睡眠/唤醒事件完全无法触发:
1. AppDelegate未关联到SwiftUI应用实例
你定义了AppDelegate类,但没有让SwiftUI的NotificationsApp加载这个代理。在macOS的SwiftUI应用中,必须通过@NSApplicationDelegateAdaptor属性包装器关联自定义代理,否则applicationDidFinishLaunching方法永远不会执行,监听器自然无法完成注册。
2. Selector与目标方法不匹配
- 你用字符串形式的
Selector(("sleepListener"))注册监听器,但AppDelegate内的sleepListener是带Notification参数的方法,而全局的sleepListener是无参函数且未标记@objc,系统无法找到正确的目标方法。 - 你为
didWakeNotification注册了wakeUpListener,但AppDelegate内根本没有这个方法,全局的同名函数同样缺少@objc标记,无法被Selector识别。
3. 方法访问权限与语法问题
AppDelegate内的sleepListener被标记为private,虽然加了@objc,但字符串形式的Selector可能无法正确访问;同时使用字符串Selector本身就容易出现拼写错误,不如类型安全的#selector语法可靠。
修复后的完整代码
import SwiftUI @main struct NotificationsApp: App { // 关联自定义AppDelegate @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate var body: some Scene { WindowGroup { ContentView() } } class AppDelegate: NSObject, NSApplicationDelegate { func applicationDidFinishLaunching(_ aNotification: Notification) { // 使用类型安全的#selector语法注册监听器 let workspaceCenter = NSWorkspace.shared.notificationCenter workspaceCenter.addObserver( self, selector: #selector(sleepListener(_:)), name: NSWorkspace.willSleepNotification, object: nil ) workspaceCenter.addObserver( self, selector: #selector(wakeUpListener(_:)), name: NSWorkspace.didWakeNotification, object: nil ) } @objc func sleepListener(_ aNotification: Notification) { print("Going to sleep") } @objc func wakeUpListener(_ aNotification: Notification) { print("Woke up") } } }
额外优化建议
如果想统一处理多个通知,可以注册同一个方法,通过判断通知名称区分事件:
func applicationDidFinishLaunching(_ aNotification: Notification) { let workspaceCenter = NSWorkspace.shared.notificationCenter workspaceCenter.addObserver( self, selector: #selector(handleWorkspaceEvent(_:)), name: NSWorkspace.willSleepNotification, object: nil ) workspaceCenter.addObserver( self, selector: #selector(handleWorkspaceEvent(_:)), name: NSWorkspace.didWakeNotification, object: nil ) } @objc func handleWorkspaceEvent(_ aNotification: Notification) { switch aNotification.name { case NSWorkspace.willSleepNotification: print("系统即将进入睡眠") case NSWorkspace.didWakeNotification: print("系统已唤醒") default: print("收到未知工作区通知") } }
内容的提问来源于stack exchange,提问作者ian
相关产品推荐
相关产品推荐

