为 Swift Objects/Properties 设置观察者

Setting Observer for Swift Objects/Properties

我一直在寻找一种在连接到 mac 的显示器数量发生变化时触发方法的方法。我知道我可以获得 NSScreen.screens.count 的值,但我需要找到一种方法来创建通知或在该值更改时创建通知或其他内容以指示连接的显示器数量发生变化。

我已经尝试过 KVO 示例 here and here,但是为了使其中任何一个都起作用,需要有一个事件来触发 class.

中的方法

本质上,这是我想根据第一个 link:

做的

class EventObserverDemo {
    var statusObserver: NSKeyValueObservation?
    var objectToObserve: NSScreen.screens.count?
    
    func registerAddObserver() -> Void {
        statusObserver = objectToObserve?.observe(NSScreen.screens.count, options: [.new, .old], changeHandler: {[weak self] (NSScreen.screens.count, change) in
            if let value = change.newValue {
                // observed changed value and do the task here on change.
                print("The display count has changed.")
            }
        })
    }
    
    func unregisterObserver() -> Void {
        if let sObserver = statusObserver {
            sObserver.invalidate()
            statusObserver = nil
        }
    }
}

我尝试使用使用 NSScreen.colorSpaceDidChangeNotification 的通知,但如果显示器断开连接则不会触发通知。

我想找到一种方法来检测外部显示器何时连接或断开连接。必须有一些我还没有找到的东西,因为每当我将外部显示器插入 mac 时,我都会看到主显示器上的屏幕发生变化,所以无论我是否插入从我的 mac.

中显示或拔下它

我查看了 didSet 函数,但我找不到在 NSScreen.screens.count 属性 上实现它的方法。

我还查看了 NSScreen.screens.count 的 属性 包装器,但同样我也无法弄清楚。

您可以观察 NSApplication.didChangeScreenParametersNotification 通知。此示例在每次连接或断开显示器时仅打印一次,以及屏幕数量的变化。

代码:

class EventObserverDemo {
    var lastCount = NSScreen.screens.count

    init() {
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(trigger),
            name: NSApplication.didChangeScreenParametersNotification,
            object: nil
        )
    }

    @objc private func trigger(notification: NSNotification) {
        let newCount = NSScreen.screens.count

        if newCount != lastCount {
            print("Switched from \(lastCount) to \(newCount) displays")
            lastCount = newCount
        }
    }
}

你也不需要remove/invalidate观察者,更容易让系统处理它:

If your app targets iOS 9.0 and later or macOS 10.11 and later, you do not need to unregister an observer that you created with this function. If you forget or are unable to remove an observer, the system cleans up the next time it would have posted to it.