【问题标题】:Falling through to super.validateMenuItem(:) generates Swift exception通过 super.validateMenuItem(:) 生成 Swift 异常
【发布时间】:2018-03-20 15:57:02
【问题描述】:

我有一个课程MyViewController,其中包含几个从菜单项触发的操作。

class MyViewController: NSViewController { … }

动作连接到 IB 中的第一响应者。操作如下所示:

@IBAction func removeSelectedItems(_ sender: AnyObject) {
    arrayController.remove(contentsOf: arrayController.selectedObjects)
}

validateMenuItem(:) 代码如下:

override func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
    let selection = arrayController.selectedObjects

    if (menuItem.action == #selector(removeSelectedItems(_:))) {
        return selection!.count > 0
    }

    return super.validateMenuItem(menuItem)
}

当我在if() 列表中包含这些操作时,一切都很好。但如果我不这样做,并且validateMenuItem(:) 落入 super,我会得到一个例外:

[MyApp.MyViewController validateMenuItem:]: unrecognized selector sent to instance 0x618000165ac0

如果我在方法结束时改为return false,也不例外。

validateMenuItem(:) 被调用时会发生这种情况,例如打开菜单时。尽管如此,当项目被选中时会触发该操作。

在方法结束时调用super 是不是错了?我希望在找到匹配项之前查询响应者链,而不是声称我没有实现我明确执行的方法的异常!

【问题讨论】:

  • 我只是好奇,当你在被覆盖函数的开头和被覆盖函数的结尾使用super.validateMenuItem(:)时会有变化吗?
  • 不,底层状态不会改变。

标签: swift macos exception super nsmenuitem


【解决方案1】:

在方法结束时调用 super 是不是我错了

是的。 NSViewController 和它的任何超类都没有实现validateMenuItem。尽管 Swift 中有override,但它实际上并没有被继承。它通过非正式协议(NSMenuValidation)注入到 Objective-C 中。 [Swift 编译器不理解这种诡计;因此override 尽管我们没有覆盖任何东西。]

https://forums.developer.apple.com/thread/46772

【讨论】:

  • 但是真正的问题是你根本不应该使用validateMenuItem:
  • “我希望在找到匹配项之前查询响应者链”然后您需要再次阅读菜单验证文档。 :)
  • 谢谢,这正是我所需要的。我现在已经可以使用validateUserInterfaceItem(:) 了——只需要实现NSUserInterfaceValidations 协议。我看到响应者链检查只是碰巧找到了实现该动作的对象。尽管如此,异常声称我的课程没有实现validateMenuItem(:)!
  • "尽管如此,异常声称我的类没有实现 validateMenuItem(:)" 这不是它所声称的,这仍然是非常令人困惑的。故事中只有一个实例:您的 MyViewController。这是通过调用super 发送消息的实例。这就是MyApp.MyViewController 在异常日志中所说的。好的,那么运行时会尝试处理该消息。实例的类实现了validateMenuItem,是的。但是它的 superclass 没有(并继承)这样的实现。这就是super 正在寻找的东西。
  • 我想我读到如果NSMenuItem 的目标为 nil,它将跟随响应者链,找到响应其操作的第一个类。
猜你喜欢
  • 2016-09-11
  • 1970-01-01
  • 2012-08-21
  • 2013-04-08
  • 1970-01-01
  • 2011-05-30
  • 2018-12-11
  • 2019-03-25
  • 2019-10-13
相关资源
最近更新 更多