Vous n'avez pas besoin de vérifier que l'initialiseur délégué a réussi. Si l'initialiseur délégué a échoué, tout le processus d'initialisation échoue.
Cela est évident dans ce code:
class EvenNumber {
var num: Int
var stringValue: String
init?(n: Int) {
guard n % 2 == 0 else { return nil }
self.num = n
stringValue = "" // vous avez oublié d'initialiser stringValue dans vos deux initialiseurs
}
// vous avez oublié "convenience"
convenience init?(str: String) {
guard let n = Int(str) else { return nil }
self.init(n: n)
print("hello")
stringValue = ""
}
}
EvenNumber(str: "5")
"hello" n'est pas imprimé, ce qui signifie que le reste de l'initialisation ne s'exécute pas si init(n:)
échoue.
Voici une documentation en soutien (vous devez faire défiler un peu, sous "Propagation de l'échec d'initialisation"):
Dans les deux cas, si vous déléguez à un autre initialiseur causant un échec d'initialisation, l'ensemble du processus d'initialisation échoue immédiatement et aucun autre code d'initialisation n'est exécuté.
(Cette section est incluse pour plus de clarté.)
Maintenant, vous (ou quiconque consultera cette question à l'avenir) pourriez demander : "mais que se passe-t-il si je veux faire quelque chose d'autre si l'initialiseur délégué échoue?" Dans ce cas, vous devez vérifier la condition qui provoque l'échec de l'initialiseur:
if n % 2 == 1 {
self.init(n: n)
} else {
// faire autre chose
}
Pourquoi est-ce si "maladroit"? Eh bien, disons que vous pouviez faire ceci (attention : syntaxe inventée):
if self.init(n: n) {
// succès!
} else {
// échec
}
Pour arriver à la branche "échec", nous devons avoir déjà exécuté self.init(n:)
. self.init(n:)
, avant d'échouer, pourrait déjà avoir initialisé certaines propriétés let
. Rappelez-vous que les propriétés let
ne peuvent être initialisées qu'une fois. Donc maintenant self.init(n: n)
a été exécuté, mais le compilateur ne sait pas quelles propriétés let
ont été initialisées. Voyez-vous le problème? Comment le compilateur va-t-il vérifier que vous avez initialisé chaque propriété exactement une fois dans la branche "échec"?