我有一个班级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(:)
落到了超级,我会得到一个例外:
[MyApp.MyViewController validateMenuItem:]: unrecognized selector sent to instance 0x618000165ac0
如果我在方法结束时代替return false
,则没有例外。
调用validateMenuItem(:)
时会发生这种情况,例如菜单打开时。尽管如此,在选择项目时会触发操作。
在方法结束时调用super
我错了吗?我希望在找到匹配项之前查询响应者链,而不是声称我没有实现我明显做过的方法的例外情况!
答案 0 :(得分:2)
在方法结束时调用super是错误的
是。 NSViewController和它的任何超类都没有实现validateMenuItem
。尽管Swift中有override
,但它实际上并没有被继承。它通过非正式协议(NSMenuValidation)在Objective-C中注入。 [Swift编译器不理解那种技巧;因此override
尽管事实上我们没有压倒任何东西。]