Avec le code suivant, j'essaye de définir une classe de modèle simple et c'est un initialiseur disponible, qui prend un dictionnaire (json-) comme paramètre. L'initialiseur doit retourner nil
si le nom d'utilisateur n'est pas défini dans le json d'origine.
1. Pourquoi le code ne se compile-t-il pas? Le message d'erreur dit:
Toutes les propriétés stockées d'une instance de classe doivent être initialisées avant de renvoyer nil à partir d'un initialiseur.
Cela n'a pas de sens. Pourquoi devrais-je initialiser ces propriétés lorsque je prévois de revenir nil
?
2. Mon approche est-elle la bonne ou y aurait-il d'autres idées ou modèles communs pour atteindre mon objectif?
class User: NSObject {
let userName: String
let isSuperUser: Bool = false
let someDetails: [String]?
init?(dictionary: NSDictionary) {
if let value: String = dictionary["user_name"] as? String {
userName = value
}
else {
return nil
}
if let value: Bool = dictionary["super_user"] as? Bool {
isSuperUser = value
}
someDetails = dictionary["some_details"] as? Array
super.init()
}
}
swift
object-initializers
Kai Huppmann
la source
la source
canSetCalculableProperties
paramètre booléen permettant à mon initialiseur de calculer des propriétés qui peuvent ou ne peuvent pas être créées à la volée. Par exemple, si unedateCreated
clé est manquante et que je peux définir la propriété à la volée parce que lecanSetCalculableProperties
paramètre est vrai, je la mets simplement à la date actuelle.Réponses:
Mise à jour: à partir du journal des modifications de Swift 2.2 (publié le 21 mars 2016):
Pour Swift 2.1 et versions antérieures:
Selon la documentation d'Apple (et l'erreur de votre compilateur), une classe doit initialiser toutes ses propriétés stockées avant de revenir
nil
depuis un initialiseur disponible:Remarque: cela fonctionne bien pour les structures et les énumérations, mais pas pour les classes.
La méthode suggérée pour gérer les propriétés stockées qui ne peuvent pas être initialisées avant l'échec de l'initialiseur est de les déclarer comme des options implicitement déballées.
Exemple tiré de la documentation:
Dans votre cas, cependant, définir simplement
userName
commeString!
ne résout pas l'erreur de compilation parce que vous avez encore à vous soucier de l' initialisation des propriétés de votre classe de base,NSObject
. Heureusement, avecuserName
défini comme aString!
, vous pouvez réellement appelersuper.init()
avant vous,return nil
ce qui initiera votreNSObject
classe de base et corrigera l'erreur de compilation.la source
Product
classe) ne peut pas déclencher un échec d'initialisation avant d'attribuer une valeur spécifique, même si la documentation le dit. Les documents ne sont pas synchronisés avec la dernière version de Swift. Il est conseillé d'en faire unvar
pour l'instant à la placelet
. source: Chris Lattner .Selon Chris Lattner, c'est un bug. Voici ce qu'il dit:
La source
ÉDITER:
Donc, swift est maintenant open source et selon ce journal des modifications, il est maintenant corrigé dans les instantanés de swift 2.2
la source
J'accepte que la réponse de Mike S soit la recommandation d'Apple, mais je ne pense pas que ce soit la meilleure pratique. L'intérêt d'un système de type fort est de déplacer les erreurs d'exécution vers la compilation. Cette «solution» va à l'encontre de cet objectif. IMHO, mieux serait d'aller de l'avant et d'initialiser le nom d'utilisateur
""
, puis de le vérifier après le super.init (). Si des noms d'utilisateur vides sont autorisés, définissez un indicateur.la source
Une autre façon de contourner la limitation est de travailler avec une classe-fonctions pour faire l'initialisation. Vous pourriez même vouloir déplacer cette fonction vers une extension:
L'utiliser deviendrait:
la source
Bien que Swift 2.2 ait été publié et que vous n'ayez plus à initialiser complètement l'objet avant d'échouer l'initialiseur, vous devez tenir vos chevaux jusqu'à ce que https://bugs.swift.org/browse/SR-704 soit corrigé.
la source
J'ai découvert que cela pouvait être fait dans Swift 1.2
Il y a quelques conditions:
Exemple:
la source
Extrait de: Apple Inc. « Le langage de programmation Swift. «IBooks. https://itun.es/sg/jEUH0.l
la source
Vous pouvez utiliser l' init de commodité :
la source