我可以观察 swift 中的可选值吗?如果不是,我将如何尝试观察变化?

Can I observe an optional value in swift? If not, how might I go about attempting to observe a change?

我正在尝试观察 Swift 中 NSPopUpButton 选择的变化。在我的视图控制器的 viewDidLoad() 中,我设置了观察标记以观察 selectedItem 属性 的 NSPopUpButton

override func viewDidLoad() {
    super.viewDidLoad()

    observation = observe(\.myPopUpButton.selectedItem) {
        objectToObserve, change in

        if change.kind == NSKeyValueObservedChange.Kind.setting {
            // code to execute goes here
        }
}

我在设置了observation的那一行设置了一个断点,以确定令牌是用正确的密钥路径配置的。我还在闭包内设置了一个 break 以查看它何时执行。当我更改 NSPopUpButton 的选择时,闭包不执行。

selectedItemNSMenuItem? 类型,所以我怀疑我无法对可选的 属性 设置观察。但我在 Apple 的文档中找不到任何说明情况是否如此的内容,我不确定我将如何为自己进行验证。

所以我有一些主要问题和一些后续问题:

我已经尝试过的疑难解答...

许多 AppKit 对象的许多属性不是KVO-compliant。除非文档明确说明 属性 是合规的,否则您应该假定它不合规。 NSPopUpButtonselectedItem 属性 是 non-compliant。

通知 pop-up 按钮的选定项已更改的最简单方法是设置按钮的 targetaction:

    override func viewDidLoad() {
        super.viewDidLoad()
        myPopUpButton.target = self
        myPopUpButton.action = #selector(popUpButtonDidFire(_:))
    }

    @IBAction private func popUpButtonDidFire(_ sender: Any) {
        // code to execute goes here
    }

请注意,如果您在故事板或 xib 中创建 pop-up 按钮,您可以通过 pop-up 中的 control-dragging 将其连接到 popUpButtonDidFire 方法按钮到视图控制器。

如 macOS Cocoa 中的评论所述,绑定和 Swift 的 属性 观察者是一种非常强大的观察值的方式,即使在之前的 Swift 版本中也是如此.不需要插座。

创建一个 属性 并使用 didSet 观察者

@objc dynamic var selectedObject : MyObject?  {
    didSet {

    }
}

在 Bindings Inspector 的 Interface Builder 中将 Selected Object 绑定到目标控制器 Model Key Path > selectedObject.

MyObject是菜单项表示对象的类型。如果未选择任何内容,则 selectedObjectnil。您还可以绑定 Selected IndexSelected TagSelected Value(但不能同时绑定)。