Dictionary VS NSDictionary
NiClou
Membre
Hello,
Comme beaucoup je m'essaie au Swift et je rencontre quelques problèmes.
J'ai la méthode d'exemple suivante:
-(void)handleInformations:(NSDictionary*)infos{
if (!infos)
return ;
if ([infos objectForKey:@p])
[self goToScreen:[infos objectForKey:@p]];
}
Lorsque j'essaie de la ré ecrire en swift, je suis confronté a des problèmes swift.
Problème que je ne rencontre pas si j'utilise un NSDictionary.
func handleInformations(infos: Dictionary<String, Int>) {
if (infos.isEmpty) {
return
}
if (infos["p"] != nil) {
self.goToScreen(infos["p"] as Int) //La j'ai un problème
}
}
L'erreur est la suivante:
Could not find an overload for 'subscript' that accepts the supplied arguments
Des idées?
EDIT: CocoaCafe est un bon RubberDuck: La méthode goToScreen attendait un String et j'ai oublié le "!" après le "as Int"...
J'ai vraiment du mal avec ces "?/!"
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Avec le Dictionary, ce n'est pas nécessaire d'utiliser infos["p"] asInt, car c'est un Dictionary<String, Int>, du coup la valeur renvoyé sera toujours un Int.
Plus exactement la valeur renvoyée par infos["p"] ne sera pas un "Int" mais sera un "Int?" (c'est à dire un Optional<Int>) puisque tu peux ne pas avoir de valeur dans le dictionnaire pour la clé demandée, donc il peut tout à fait retourner nil (= "Optional.None", soit une absence de valeur).
Et du coup il faut en effet :
La syntaxe "if let xx = optionalExpr" teste si l'expression optionalExpr (qui est une expression retournant un optional) retourne une valeur.
Cette syntaxe de l'Optional Binding ("if let ...") est beaucoup + dans l'esprit de Swift que la méthode "à la Objective-C" de faire "if (infos["p"] != nil) { /* code qui utilise infos["p"] */ }". Elle a en plus l'avantage de ne faire le "lookup" / calcul de l'expression qu'une seule fois (il ne cherche la valeur de la clé "p" dans le dictionnaire "infos" qu'une seule fois, et s'il la trouve il l'affecte à screenNum " contrairement à si tu utilisais infos["p"] à la fois dans la condition et dans le corps du "if" à la mode Objective-C où il aurait à évaluer l'expression / rechercher la valeur dans le dico 2 fois)
En fait en pratique, c'est très rare d'avoir à mettre un "!" derrière une variable ou d'avoir à forcer un cast en un "Type!". Il faut toujours préférer soit l'Optional Binding, soit l'Optional Chaining (utilisation du "?" après la variable), selon les cas / le besoin.
Faire du forced-unwrapping avec "!" c'est risquer le crash au Runtime si la variable est nil et qu'on force à l'unwrapper quand même " plantage assuré par définition. Alors que l'Optional Binding permet de s'assurer qu'on n'unwrap pas un Optional (qu'on n'essaye pas d'accéder à sa valeur interne) dans le cas où ce dernier est nil (n'a en fait pas de valeur interne, donc).
Merci pour ces précisions plus précis.
J'ai évité la complexité en évitant d'être trop complexe. :P
Whouaou.
Ya beaucoup de choses qui s'expliquent en effet.
C'est vrai qu'on a très peu d'informations concernant les bonnes méthodes à utiliser.
Merci a vous deux pour ces réponses, on ne peut plus precise.