Mise à jour: à partir du journal des modifications de Swift 2.2 (publié le 21 mars 2016):
Les initialiseurs de classe désignés déclarés comme disponibles ou lancés peuvent désormais renvoyer nil ou générer une erreur, respectivement, avant que l'objet n'ait été complètement initialisé.
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:
Pour les classes, cependant, un initialiseur disponible peut déclencher un échec d'initialisation uniquement après que toutes les propriétés stockées introduites par cette classe ont été définies sur une valeur initiale et que toute délégation d'initialisation a eu lieu.
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:
class Product {
let name: String!
init?(name: String) {
if name.isEmpty { return nil }
self.name = name
}
}
Dans l'exemple ci-dessus, la propriété name de la classe Product est définie comme ayant un type de chaîne facultatif implicitement déroulé (String!). Etant donné qu'elle est de type facultatif, cela signifie que la propriété name a une valeur par défaut de nil avant de recevoir une valeur spécifique lors de l'initialisation. Cette valeur par défaut de nil signifie à son tour que toutes les propriétés introduites par la classe Product ont une valeur initiale valide. Par conséquent, l'initialiseur disponible pour Product peut déclencher un échec d'initialisation au début de l'initialiseur s'il reçoit une chaîne vide, avant d'affecter une valeur spécifique à la propriété name dans l'initialiseur.
Dans votre cas, cependant, définir simplement userName
comme String!
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, avec userName
défini comme a String!
, vous pouvez réellement appeler super.init()
avant vous, return nil
ce qui initiera votre NSObject
classe de base et corrigera l'erreur de compilation.
class User: NSObject {
let userName: String!
let isSuperUser: Bool = false
let someDetails: [String]?
init?(dictionary: NSDictionary) {
super.init()
if let value = dictionary["user_name"] as? String {
self.userName = value
}
else {
return nil
}
if let value: Bool = dictionary["super_user"] as? Bool {
self.isSuperUser = value
}
self.someDetails = dictionary["some_details"] as? Array
}
}
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.