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.

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. :slight_smile:

In addition it does not apply to an action specified as a String parameter.

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).