J'ai un nom de variable d'instance dans String
var name: String
Ma classe implémente le protocole NSCoding. Donc, pour le nom que j'avais
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(self.name, forKey: kName)
}
required init(coder aDecoder: NSCoder) {
self.name = aDecoder.decodeObjectForKey(kName) as String // CRASH HERE
}
Résultat? Je commençais à avoir un crash lors de l’initiation au décodeur. J'ai changé init en ceci:
var temp = aDecoder.decodeObjectForKey(kName) as NSString!
self.name = aDecoder.decodeObjectForKey(kName) as String
et réalisé que la valeur temp maintient la bonne valeur NSString. alors j'ai pensé que la ligne ci-dessous va résoudre ce problème, mais il génère une erreur de l'éditeur de liens:
self.name = aDecoder.decodeObjectForKey(kName) as NSString!
la question est de savoir comment prendre le temp et le mettre en nom?
decodeObjectForKey
renvoie un AnyObject?
facultatif. Vous devez donc protéger votre code contre les éventuelles valeurs nil. Utiliser un casting pour un forcé déballé ne semble pas sans danger.
Je ne parviens pas à reproduire l'erreur (le problème pourrait donc se trouver ailleurs dans votre code), mais voici comment je procéderais lors de l'initialisation de la propriété name
:
var tempName = aDecoder.decodeObjectForKey("name") as? String
if let tempName = tempName {
self.name = tempName
} else {
self.name = "some initial value"
}
Notez l'utilisation de l'option as?
optionnelle en downcast, qui produit toujours un résultat (nil ou une valeur de type valide) par opposition à as NSString!
, qui déclenche une exception si l'abaissement n'est pas possible int à la place).
Ce code vous permettrait également d'améliorer le débogage - si tempName
est nil
, la clé n'existe pas ou la valeur correspondante est d'un type différent.
Il y avait deux choses que je devais faire pour que cela fonctionne:
Pour une raison quelconque, le pontage entre NSString et String ne fonctionne pas dans cette situation. donc le casting devrait être fait en deux étapes
if let name = aDecoder.decodeObjectForKey(kName) as? NSString {
self.name = name as String
} else {
assert(false, "ERROR: could not decode")
self.name = "ERROR"
}