NSStatusItem.isVisible 上的 KVO 触发两次

KVO on NSStatusItem.isVisible fires twice

我正在尝试使用键值观察来确定用户何时使用 removalAllowed 行为将 NSStatusItem 拖出菜单栏。根据文档,这是受支持的:

Status items with this behavior allow interactive removal from the menu bar. Upon removal, the item’s isVisible property changes to false. This change is observable using key-value observation.

但是,每当 isVisible 属性 更改时,回调函数似乎会触发两次。这是一个最小的示例(假设 statusItemobserver 是在应用程序的生命周期内保留的变量,例如在 AppDelegate 上)。

statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength)
statusItem.button!.image = NSImage(named: NSImage.addTemplateName)
statusItem.behavior = .removalAllowed

observer = statusItem.observe(\.isVisible, options: [.old, .new]) { object, change in
    print("oldValue: \(change.oldValue!) newValue: \(change.newValue!)")
}

如果将图标拖出菜单栏,将打印以下内容:

oldValue: false newValue: true
oldValue: false newValue: true

我查看了 change 对象上的每个 属性,据我所知,它们都是相同的,因此没有简单的方法可以丢弃重复项事件。我也搞砸了 prior 选项,这似乎也没有帮助。

消除重复项的明智方法是用 Combine 发布者替换 KVO 观察者。

import Combine

var cancellable : AnyCancellable?

cancellable = statusItem.publisher(for: \.isVisible)
    .removeDuplicates()
    .sink { value in
        print(value)
    }

如果您对旧值感兴趣,可以添加 Scan 运算符