在Swift 4中收听NSWorkspace通知

问题描述:

当计算机的显示器进入睡眠状态时,下面的简单Swift 4示例应该停止。在Swift 4中收听NSWorkspace通知

class Observer { 
    var asleep = false 

    func addDNC() { 
     NSWorkspace.shared.notificationCenter.addObserver(forName: NSWorkspace.screensDidSleepNotification, object: nil, queue: nil, using: notificationRecieved) 
    } 

    func notificationRecieved (n: Notification) { 
     asleep = true 
    } 
} 

let observer = Observer() 
observer.addDNC() 

while (!observer.asleep) {} 
print ("zzzz") 

但是,程序陷在while循环。我做错了什么,以及等待通知的正确方法是什么?

我试过使用选择器(#selector (notificationRecieved),当然函数声明@objc),无济于事。

+0

如果你打算用while运行它,那么为什么你甚至需要首先创建一个通知观察者对象呢? –

+0

这只是一个例子。但是,我找不到手动检查睡眠状态的方法。除了使用通知之外,如果有办法做到这一点,你能告诉我在哪里可以找到解释吗?谢谢。 @ElTomato –

开始在Xcode中模板的应用程序和修改ViewController.swift做到这一点:

import Cocoa 

class Observer { 
    var asleep = false 

    func addDNC() { 
     NSWorkspace.shared.notificationCenter.addObserver(forName: NSWorkspace.screensDidSleepNotification, object: nil, queue: nil, using: notificationRecieved) 
    } 

    func notificationRecieved (n: Notification) { 
     print("got sleep notification!") 
     asleep = true 
    } 
} 

class ViewController: NSViewController { 

    let observer = Observer() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // Do any additional setup after loading the view. 

     observer.addDNC() 
    } 

    override var representedObject: Any? { 
     didSet { 
     // Update the view, if already loaded. 
     } 
    } 


} 

你的代码和我之间的区别是,我不会做你正在做的古怪困轮询的事情(这将导致旋转的披萨光标),并且我还将observer设置为关闭对象的属性,因此只要视图控制器具有observer属性即可。

+0

使用viewDidLoad观察通知听起来不对。 –

+0

'Observer'类的设置方式,我认为'viewDidLoad'与任何​​调用'addDNC'都是一样的好地方。如果这是我的代码,我可能会直接设置观察者而不使用单独的类。你在想什么? –

+0

让观察者在实际的应用程序中工作,就像你做的那样。我认为我的例子中的while循环实际上阻止了观察者停止工作。 (回答迟了,因为我刚刚意识到我没有把问题标记为答案) –