【问题标题】:KVO on NSStatusItem.isVisible fires twiceNSStatusItem.isVisible 上的 KVO 触发两次
【发布时间】:2021-11-04 03:24:21
【问题描述】:

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

具有此行为的状态项允许从菜单栏中交互式删除。移除后,该项目的 isVisible 属性更改为 false。 使用键值观察可以观察到这种变化。

但是,每当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 选项,这似乎也没有帮助。

【问题讨论】:

    标签: swift appkit key-value-observing nsstatusitem


    【解决方案1】:

    摆脱重复的聪明方法是用组合发布者替换 KVO 观察者。

    import Combine
    
    var cancellable : AnyCancellable?
    
    cancellable = statusItem.publisher(for: \.isVisible)
        .removeDuplicates()
        .sink { value in
            print(value)
        }
    

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

    【讨论】:

    • 优秀的解决方法,谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多