Utiliser les sélecteurs en Swift
Pour ceux qui ne s'en rappelle plus les sélecteurs étaient des objets permettant de sélectionner une méthode pour une autre méthode afin qu'elle l'invoque dynamiquement durant son exécution.
[NSTimer scheduledTimerWithTimeInterval:2.0
target:self
selector:@selector(targetMethod:)
userInfo:nil
repeats:NO];
Le sélecteur que l'on passe en paramètre ici sélectionne une méthode s'appelant tergetMethod
et prenant un paramètre.
Le sélecteur en Swift 1.0
Les sélecteurs existent aussi en swift. En swift 1.0 il suffisait de passer une chaîne de caractère du même format qu'en objective-C qui indiquait le nom de la méthode à sélectionner comme ci-dessous.
NSTimer.scheduledTimerWithTimeInterval(1,
target: self,
selector: "addOne:",
userInfo: nil,
repeats: true)
Le sélecteur en Swift 2.0
En Swift 2.0 il n'y a pas grand-chose qui change : le langage ne veut juste plus se contenter d'une chaîne de caractère.
On crée donc un objet de type Selector
comme ci-dessous :
NSTimer.scheduledTimerWithTimeInterval(1,
target: self,
selector: Selector("addOne:"),
userInfo: nil,
repeats: true)
Tout aussi simple qu'avant donc ; il faut juste le savoir.
Notez qu'il est aussi possible d'utiliser une variable de type Selector
et tous les avantages que cela implique pour accomplir le travail.
let timerSelector: Selector = Selector("addOne:")
NSTimer.scheduledTimerWithTimeInterval(1,
target: self,
selector: timerSelector,
userInfo: nil,
repeats: true)
Méthodes privées
Attention cependant aux méthodes privée. Le code ci-dessus ne fonctionnerait pas si la méthode addOne(_:)
était marquée comme privée.
Selon la doc d'Apple, les méthodes privées ne sont pas montrées au runtime
Objective-C. Vous aurez donc une erreur du type :
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[App.Controller addOne:]: unrecognized selector sent to instance XXX
Deux solutions s'offrent donc à vous :
- Rendre votre méthode publique
- Utiliser
@objc
devant la déclaration de votre méthode comme ceci :@objc private func addOne(_: Integer)
Les nouveautés de Swift 2.2
Comme pour Swift 2.0, les changements syntaxiques apporté par Swift 2.2 ne sont pas énorme. Jugez par vous-même :
NSTimer.scheduledTimerWithTimeInterval(1,
target: self,
selector: #selector(addOne:),
userInfo: nil,
repeats: true)
L'intérêt de ce changement ? Le sélecteur n'est plus qu'une simple string
. Avec cette nouvelle syntaxe, le sélecteur est vérifié à la compilation : si la fonction sélectionnée n'existe pas une erreur est levé.
On évite ainsi des erreurs improbables. On gagne du temps de débogage et ça, c’est beau.
Pour aller plus loin :