Erreur fatale : Nil trouvé de manière inattendue lors du déballage d'une valeur facultative (2023)

Qu'est-ce qu'un Facultatif (arrière-plan) ?

Dans Swift, une option est une constante ou une variable qui peut contenir une valeur OU aucune valeurnéantdu type d'origine. Cette valeur est notée "?". Une valeur facultative doit êtredéballé.

Donc, en d'autres termes, un facultatif est en fait unrécipientouemballage.

Le"!"l'opérateur est unforcer le dérouleurqui expose ce qu'il y a dansrécipient. Il dit "croyez-moi, je sais ce que je fais, je sais que la valeur est là, la valeur n'est pas nulle" lorsque vous exécutez le code. Si vous vous trompezaccident.

A moins que tu ne sois vraimentsavoirque fais tu. Évitez d'utiliser le"!"forcer l'opérateur de déballage. Probablement la principale cause de plantages pour les programmeurs Swift débutants.

Gérer les options (la pire façon)

Pourquoi ai-je reçu "Erreur fatale : zéro trouvé de manière inattendue lors du déballage d'une valeur facultative" ?

Vous avez probablement fait l'une des actions suivantes.

1. Déballage explicite de la force

Cela se fait avec le ! opérateur sur une option. Par exemple:

laisserchaîne facultative :Chaîne?imprimer(chaîne facultative !)// <- CRASH

Erreur fatale : Nil trouvé de manière inattendue lors du déballage d'une valeur facultative

Commechaîne facultativeestnéantici, vous obtiendrez un plantage sur la ligne où vous forcez à le déballer.

2. Options implicitement déballées

Ceux-ci sont définis avec un!, Plutôt qu'un?après le type.

étaitEntier facultatif :Int ! // cette valeur est implicitement désencapsulée partout où elle est utilisée

Ces options sont supposées contenir une valeur. Par conséquent, chaque fois que vous accédez à une option implicitement déballée, elle sera automatiquement déballée de force pour vous. S'il ne contient pas de valeur, il plantera.

imprimer(Entier facultatif)// <- CRASH

Erreur fatale : Nil trouvé de manière inattendue alors queimplicitementdéballage d'une valeur facultative

IBOutlets, sont souvent des options implicitement déballées. En effet, le xib ou le storyboard reliera les points de venteseulà l'exécution, après l'initialisation. Par conséquent, vous devez vous assurer que vous n'accédez pas aux prises avant qu'elles ne soient chargées en mémoire. Assurez-vous également que les connexions sont correctes dans votre storyboard ou fichier xib, sinon les valeurs serontnéantlors de l'exécution, donc plantage lors de la première utilisation. Si vous essayez de corriger cette erreur (connexions), essayez de supprimer les lignes de code qui définissent vos points de vente, supprimez le lien du xib ou du storyboard s'il est toujours là, puis reconnectez-les.

Si vous voulez un commentaire de guide complet ci-dessous.

3. Lancements forcés (vers le bas)

laissermaChaîne = uneFormecomme!Chaîne

Ici, en forçant le casting, vous dites au compilateur de ne plus s'inquiéter, car vous aurez toujours unChaîneexemple là. Et tant que cela tient, vous n'avez pas à vous inquiéter. Les problèmes commencent lorsque vous ou vos partenaires de code du projet commencez à faire circuler des valeurs non-String. Crash !!

4. Valeurs provenant d'Objective-C

Valeurs provenant d'Objective-C qui n'ont pas d'annotations de nullabilité. Supposons que nous ayons la classe Objective-C suivante :

@interfaceMonUtilisateur:NSObject@propriétéNSString*nom;@fin

Maintenant, si aucune annotation de nullabilité n'est spécifiée (soit explicitement, soit via NS_ASSUME_NONNULL_BEGIN/NS_ASSUME_NONNULL_END), alors la propriété name sera importée dans Swift en tant que chaîne ! (un IUO - facultatif implicitement déballé). Dès qu'un code Swift voudra utiliser la valeur, il plantera si name vaut nil.

Traiter en toute sécurité avec les options (la meilleure façon)

Solutions? Il existe de nombreuses façons de traiter les options qui sontplus sûr.

Swift est un langage de type sécurisé, ce qui signifie que le langage vous aide à être clair sur les types de valeurs avec lesquelles votre code peut fonctionner. Si une partie de votre code nécessite une chaîne, la sécurité de type vous empêche de lui transmettre un Int par erreur. De même, la sécurité de type vous empêche de transmettre accidentellement une chaîne facultative à un morceau de code qui nécessite une chaîne non facultative. La sécurité des types vous aide à détecter et à corriger les erreurs le plus tôt possible dans le processus de développement.

1. Reliure facultative

Cela vous permet de vérifier si une option contient une valeur et vous permet d'affecter la valeur non enveloppée à une nouvelle variable ou constante.

si laissernombre = entier facultatif {imprimer("Contient une valeur ! C'est \(nombre) !")}autre{imprimer("Ne contient pas de chiffre")}

Ce que cela fait, c'est d'abord vérifier que l'optionnel contient une valeur. Si c'est le cas, la valeur "déballée" est affectée à une nouvelle variable (nombre) – que vous pouvez ensuite utiliser librement comme s'il n'était pas facultatif. Si l'optionnel ne contient pas de valeur, la clause else sera invoquée, comme vous vous en doutez.

Ce qui est bien avec la liaison facultative, c'est que vous pouvez déballer plusieurs options en même temps. Vous pouvez simplement séparer les déclarations par une virgule. L'instruction réussira si toutes les options ont été déballées.

étaitoptionnelInt :Int ?étaitanOptionalString :Chaîne?si laissernombre = entier facultatif,laissertext = anOptionalString {imprimer("optionalInt contient une valeur : \(nombre). Et il en va de même pour anOptionalString, c'est : \(texte)")}autre{imprimer("Une ou plusieurs des options ne contiennent pas de valeur")}

Une autre astuce intéressante est que vous pouvez également utiliser des virgules pour vérifier une certaine condition sur la valeur, après l'avoir déballée.

si laissernombre = optionnelInt, nombre >0{imprimer("optionalInt contient une valeur : \(nombre), et elle est supérieure à zéro !")}

Le seul problème avec l'utilisation d'une liaison facultative dans une instruction if est que vous ne pouvez accéder à la valeur non encapsulée qu'à partir de la portée de l'instruction. Si vous avez besoin d'accéder à la valeur depuis l'extérieur de la portée de l'instruction, vous pouvez utiliser une instruction de garde.

2. Déclaration de garde

Une instruction de garde vous permet de définir une condition de réussite - et la portée actuelle ne continuera à s'exécuter que si cette condition est remplie. Ils sont définis avec la syntaxecondition de garde sinon {...}.

garde laissernombre = entier facultatifautre{retour}

Notez que dans le corps de garde, vous devez utiliser l'une des instructions de transfert de contrôle afin de sortir de la portée du code en cours d'exécution.

SiIntoptionnelcontient une valeur, elle sera déballée et affectée au nouveaunombreconstant. Le code après la garde continuera alors à s'exécuter. S'il ne contient pas de valeur, le gardien exécutera le code entre parenthèses, ce qui entraînera un transfert de contrôle, de sorte que le code immédiatement après ne sera pas exécuté.

La vraie chose intéressante à propos des instructions de garde est que la valeur non emballée est maintenant disponible pour être utilisée dans le code qui suit l'instruction (car nous savons que le futur code ne peut s'exécuter que si l'option a une valeur). C'est un excellent moyen d'éliminer les "pyramides de malheur" créées en imbriquant plusieurs instructions if.

garde laissernombre = entier facultatifautre{retour}imprimer("optionalInt contient une valeur, et c'est : \(nombre) !")

Les gardes prennent également en charge les mêmes astuces que l'instruction if, telles que le déballage de plusieurs options en même temps et l'utilisation de la clause where.

Que vous utilisiez une instruction if ou guard dépend entièrement du fait qu'un code futur nécessite que l'option contienne une valeur.

3. Chaînage optionnel

Vous pouvez utiliser le chaînage facultatif pour appeler une méthode ou accéder à une propriété facultative. Cela se fait simplement en suffixant le nom de la variable avec un?lors de son utilisation.

Par exemple, supposons que nous ayons une variable foo, de type optionnelFooexemple.

étaittoto :Foo ?

Si nous voulions appeler une méthode surfouqui ne retourne rien, on peut simplement faire :

foo?.doSomethingInteresting()

Si foo contient une valeur, cette méthode sera appelée dessus. Si ce n'est pas le cas, rien de grave ne se produira - le code continuera simplement à s'exécuter.

Ceci est similaire à l'envoi de messages à nil en Objective-C

Cela peut donc également être utilisé pour définir des propriétés ainsi que pour appeler des méthodes. Par exemple:

toto?.bar =Bar()

Encore une fois, rien de mal ne se passera ici sifouestnéant. Votre code continuera simplement à s'exécuter.

Une autre astuce que le chaînage facultatif vous permet de faire est de vérifier si la définition d'une propriété ou l'appel d'une méthode a réussi. Vous pouvez le faire en comparant la valeur de retour ànéant.

C'est parce qu'une valeur facultative renverraAnnuler?plutôt queAnnulersur une méthode qui ne retourne rien.

Exemple:

si(foo?.bar =Bar()) !=néant{imprimer("la barre a été définie avec succès")}autre{imprimer("la barre n'a pas été définie avec succès")}

4. Opérateur de coalescence nulle

L'opérateur de coalescence nulle est une version abrégée astucieuse de l'opérateur conditionnel ternaire, principalement conçu pour convertir les options en options non optionnelles. Il a la syntaxeun ?? b, oùunest un type facultatif etbest du même genre queun(bien que généralement non facultatif).

Il vous permet essentiellement de dire « Si a contient une valeur, déballez-la. Si ce n'est pas le cas, retournez b à la place ». Par exemple, vous pouvez l'utiliser comme ceci :

laissernombre = optionnelInt ??0

Cela définira unenombreconstante deInttype, qui contiendra soit la valeur deIntoptionnel, s'il contient une valeur, ou0sinon.

C'est juste un raccourci pour:

laissernombre = optionnelInt !=néant? optionnelInt ! :0

Au revoir, C4

Top Articles
Latest Posts
Article information

Author: Prof. Nancy Dach

Last Updated: 01/09/2023

Views: 5859

Rating: 4.7 / 5 (77 voted)

Reviews: 92% of readers found this page helpful

Author information

Name: Prof. Nancy Dach

Birthday: 1993-08-23

Address: 569 Waelchi Ports, South Blainebury, LA 11589

Phone: +9958996486049

Job: Sales Manager

Hobby: Web surfing, Scuba diving, Mountaineering, Writing, Sailing, Dance, Blacksmithing

Introduction: My name is Prof. Nancy Dach, I am a lively, joyous, courageous, lovely, tender, charming, open person who loves writing and wants to share my knowledge and understanding with you.