7

In the following snippet, what is the reason why Xcode recommend "Use #selector instead of explicitly constructing a Selector"?

// addButton = UIBarButtonItem.init(barButtonSystemItem: UIBarButtonSystemItem.Add, 
//             target: self, action: #selector(FoldersMaintenanceVC.addButtonPressed))
addButton = UIBarButtonItem.init(barButtonSystemItem: UIBarButtonSystemItem.Add, 
            target: self, action: Selector("addButtonPressed"))

self.navigationItem.leftBarButtonItem = addButton

func addButtonPressed()
{
    myNslogSys2(self, funcName:#function)
}
Valentin
  • 10,769
  • 2
  • 17
  • 27
user523234
  • 14,323
  • 10
  • 62
  • 102

3 Answers3

9

It recommends that you use the Swift 2.2 new #selector because it is more type-safe since you cannot make a selector reference to a non-existing method whereas with Selector(String), you could reference a non-existing one.

Valentin
  • 10,769
  • 2
  • 17
  • 27
  • 1
    There is a flaw in this though. If I supply a wrong class that has an existing method but my intended target class - self, etc. does not have this existing method, it will crash at run time. – user523234 Apr 23 '16 at 10:50
  • What can I do if i want to do something like this: if responder!.respondsToSelector(Selector("aMethod:")) == true{ ...} – Kyle KIM May 02 '16 at 20:02
  • @KyleKIM If aMethod comes from a class or a protocol and is not optional, probably something like `if let responder = responder as? Protocol { responder.aMethod(value) }` Or otherwise `if responder!.respondToSelector(#selector(Protocol.aMethod(_:)) { ... }` – Valentin May 03 '16 at 09:15
5

Using #selector is now the correct way in Swift to reference a selector. Use of the struct Selector and string literals for selectors, such as "mySel:" have been deprecated.

The new #selector is now type safe and allows for compiler checking and autocompletion of the selector that you're passing in. This fixes the very common mistake of a spelling mistake in your selector (in the case of string literals)

Chris
  • 7,270
  • 19
  • 66
  • 110
1

It happens cause now construction of Selector from string literals deprecated and will be removed in Swift 3.0

With the introduction of the #selector syntax, we should deprecate the use of string literals to form selectors. Ideally, we could perform the deprecation in Swift 2.2 and remove the syntax entirely from Swift 3.

You can read more details about this change here https://github.com/apple/swift-evolution/blob/master/proposals/0022-objc-selectors.md

Peter K
  • 438
  • 3
  • 10