Though explicitly constructed selector is discouraged, there are cases when it cannot be avoided.
The following code traps Esc key calling goBack for the first responder supporting this action:
private let NSEscapeFinctionKey = String(UnicodeScalar(27))
private let AllModifiers: NSEvent.ModifierFlags = [.shift, .capsLock, .control, .command, .function]
class MyWindow: NSWindow {
override func keyDown(with event: NSEvent) {
if var responder = self.firstResponder,
event.modifierFlags.intersection(AllModifiers) == [],
event.characters == NSEscapeFinctionKey {
let action = Selector("goBack:")
while !responder.tryToPerform(action, with: self),
let nextResponder = responder.nextResponder {
responder = nextResponder
}
} else {
super.keyDown(with: event)
}
}
}
The code produces warning: No method declared with Objective-C selector 'goBack:' .
The warning can be silenced by placing the literal into parentheses:
let action = Selector(("goBack:")) ,
however that triggers another error: Use '#selector' instead of explicitly constructing a 'Selector' which I cannot find a way to silence. (Tried another set of parenthesizes let action = (Selector(("goBack:"))) , but the warning persisted).
As a matter of fact, Esc as a menu item shortcut does not work, so implementing it in the code seems to be the only way out.
SDGGiesbrecht
(Jeremy David Giesbrecht)
2
What makes it unavoidable? Why can you not simply use #selector like the compiler is suggesting?
// (You do not need this protocol if you already have a concrete class.)
@objc public protocol EscapeResponder {
@objc func goBack(_ sender: Any?)
}
// ...
let action = #selector(EscapeResponder.goBack(_:))
// ...
1 Like
That may be a way out. However, that makes both selector and tryToPerform
completely redundant, as instead it is possible to code
(responder as? EscapeResponder)?.goBack()
Well, it's a matter of taste, but I would better tolerate a warning, than a not quite natural code. 
In addition it does not apply to an action specified as a String parameter.
Lantua
5
While I embrace taste diversity, I think it shouldn't pull you into a discouraged practice like creating selectors from string (as it is prone to misspellings).