Cet article a pour but d’illustrer l’utilisation des optionnelles implicites au travers d’une problématique simple. Si vous avez besoin d’un petit récapitulatif sur les optionnelles avant de commencer rendez vous ici.
Problématique
Voici une classe Swift qui pourrait ressembler à cela :
class MaClasse {
let timer: NSTimer
init() {
timer = NSTimer(timeInterval: 1, target: self, selector: "tick", userInfo: nil, repeats: true)
}
func tick() {
// ...
}
}
Au premier abord tout semble correct, mais si nous écrivons ce code le compilateur va nous sortir cette erreur :
Variable ‘self.timer’ used before being initialized
Cela vient du processus d’initialisation des objets en Swift qui nous empêche de faire référence à self avant d’avoir appelé le constructeur de la super-classe. Ici comme la classe ne possède pas de super-classe nous ne pouvons pas appeler le super.init(), mais la création du NSTimer qui ne peut être nulle, nécessite une référence (croisée) avec MaClasse (self). D’où l’erreur affichée au dessus.
Solution
Comme vous l’avez deviné pour passer au travers de ce problème nous devons utiliser une optionnelle implicite. Une optionnelle implicite est une optionnelle qui contient forcément une valeur et qui est donc « ouverte » (unwrapped) par défaut. Une optionnelle implicite se déclare grâce au point d’exclamation en remplacement du point d’interrogation à la fin de son type :
class MaClasse {
// Optionnelle implicite
let timer: NSTimer!
init() {
timer = NSTimer(timeInterval: 1, target: self, selector: "tick", userInfo: nil, repeats: true)
}
}
Conclusion
Comme vous pouvez le voir les optionnelles implicites sont très utile dans les cas de référence croisée. Mais dans la majorité des cas si l’on peut utiliser des optionnels simple nous devons les privilégier pour éviter toute erreur.