Avoid using class names in Swift’s #selector

Don’t use class names in Swift 2.2’s new #selector. In other words, don’t do this:

button.addTarget(self, action: #selector(MyViewController.showLoginView), forControlEvents: .TouchUpInside)

Here’s the problem: it compiles, so you’d expect it to work, right? Isn’t that what #selector is all about? But let’s say you decided to refactor this code out of MyViewController and into a child view controller called MySecondViewController. (This just happened to me, so this is a real-world example). The code still compiles but crashes at runtime, because MySecondViewController doesn’t have a showLoginView method. Here’s the error message:

-[MyApp.MySecondViewController showLoginView]: unrecognized selector sent to instance

So don’t use the class name when you use #selector, even though Xcode’s migration tool does. Here’s a better approach:

button.addTarget(self, action: #selector(showLoginView), forControlEvents: .TouchUpInside)

It’s more concise this way, but most importantly, if you avoid using the class name in #selector, the compiler will catch your error instead of crashing at runtime.