Silencing a warning for explicitly constructed selector

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(_:))
// ...

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

Terms of Service

Privacy Policy

Cookie Policy