【问题标题】:Can I observe an optional value in swift? If not, how might I go about attempting to observe a change?我可以在 swift 中观察一个可选值吗?如果不是,我该如何尝试观察变化?
【发布时间】:2018-03-21 19:24:21
【问题描述】:

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

override func viewDidLoad() {
    super.viewDidLoad()

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

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

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

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

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

  • 我可以在 Swift 4.1 中观察一个可选属性吗?
    • 如果是这样,我该如何解决这个问题,我做错了什么?
    • 如果没有,我该如何尝试监控 NSPopUpButton 的状态?

我已经尝试过的故障排除...

  • @objc dynamic 添加到我的myPopUpButton 声明中

【问题讨论】:

标签: swift macos swift4 key-value-observing


【解决方案1】:

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

通知弹出按钮的选定项更改的最简单方法是设置按钮的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 中创建弹出式按钮,您可以通过从弹出式按钮拖动到视图控制器来将其连接到 popUpButtonDidFire 方法。

【讨论】:

  • 谢谢你,这很完美!将来,我必须记住,Apple 的文档中明确说明了符合 KVO 的属性
  • 如果选择的索引不是 KVO 可观察的,绑定是如何工作的?绑定 KVO。
  • 不,绑定不是 KVO。绑定使用 KVO 读取模型(或控制器)值,并使用KVC 设置模型(或控制器)值。但是,视图上的绑定不一定符合 KVC 或 KVO。例如,考虑NSPopUpButton 公开了一个contentObjects 绑定,但它没有contentObjects 属性。我并不是说它没有 documented contentObjects 属性;我的意思是,如果您向它发送 contentObjects 消息,您将收到无法识别的选择器错误。
【解决方案2】:

正如 macOS Cocoa Bindings 中的 cmets 和 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(但不能同时绑定)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-17
    • 2021-09-25
    • 2016-02-07
    • 2020-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-02
    相关资源
    最近更新 更多