Mon programme Swift plante EXC_BAD_INSTRUCTION
et l'une des erreurs similaires suivantes. Que signifie cette erreur et comment la corriger?
Erreur fatale: trouvé de façon inattendue nul lors du déballage d'une valeur facultative
ou
Erreur fatale: trouvé de façon inattendue nil lors du déballage implicite d'une valeur facultative
Ce message est destiné à collecter des réponses aux problèmes "inattendus trouvés nuls", afin qu'ils ne soient pas dispersés et difficiles à trouver. N'hésitez pas à ajouter votre propre réponse ou à modifier la réponse wiki existante.
Réponses:
Cette réponse est un wiki communautaire . Si vous pensez qu'il pourrait être amélioré, n'hésitez pas à le modifier !
Contexte: qu'est-ce qu'une option?
Dans Swift,
Optional
est un type générique qui peut contenir une valeur (de tout type), ou aucune valeur du tout.Dans de nombreux autres langages de programmation, une valeur "sentinelle" particulière est souvent utilisée pour manque de valeur . Dans Objective-C, par exemple,
nil
(le pointeur nul ) indique l'absence d'un objet. Mais cela devient plus délicat lorsque vous travaillez avec des types primitifs - devrait-1
être utilisé pour indiquer l'absence d'un entier, ou peutINT_MIN
- être , ou d'un autre entier? Si une valeur particulière est choisie pour signifier «aucun entier», cela signifie qu'elle ne peut plus être traitée comme une valeur valide .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 travailler. Si une partie de votre code attend une chaîne, la sécurité de type vous empêche de lui transmettre un Int par erreur.
Dans Swift, tout type peut être rendu facultatif . Une valeur facultative peut prendre n'importe quelle valeur du type d'origine ou de la valeur spéciale
nil
.Les options sont définies avec un
?
suffixe sur le type:L'absence de valeur dans une option est indiquée par
nil
:(Notez que ce
nil
n'est pas la même chose quenil
dans Objective-C. Dans Objective-C,nil
est l'absence d'un valide pointeur d'objet , à Swift, Optional ne sont pas limités à des objets / types de référence se comporte en option de façon similaire à Haskell de. Peut - être .)Pourquoi ai-je obtenu une « erreur fatale: trouvé inopinément nul lors du déballage d'une valeur facultative »?
Pour accéder à la valeur d'une option (si elle en a une), vous devez déballer . Une valeur facultative peut être dépliée en toute sécurité ou de force. Si vous décompressez une option et qu'elle n'a pas de valeur, votre programme se bloquera avec le message ci-dessus.
Xcode vous montrera le crash en mettant en évidence une ligne de code. Le problème se produit sur cette ligne.
Ce plantage peut se produire avec deux types différents de déballage forcé:
1. Déballage de force explicite
Cela se fait avec l'
!
opérateur sur une option. Par exemple:Tel
anOptionalString
quelnil
ici, vous obtiendrez un crash sur la ligne où vous forcez le déballer.2. Options optionnelles implicitement déballées
Ceux-ci sont définis avec un
!
, plutôt qu'avec un?
après le type.Ces options sont supposées contenir une valeur. Par conséquent, chaque fois que vous accédez à une option implicitement déballée, celle-ci sera automatiquement forcée pour vous. S'il ne contient pas de valeur, il se bloque.
Afin de déterminer quelle variable a provoqué le crash, vous pouvez maintenir la ⌥touche enfoncée tout en cliquant pour afficher la définition, où vous pourriez trouver le type facultatif.
Les IBOutlets, en particulier, sont généralement des options implicitement déballées. En effet, votre xib ou votre storyboard reliera les prises au moment de l'exécution, après l' initialisation. Vous devez donc vous assurer que vous n'accédez pas aux prises avant qu'elles ne soient chargées. Vous devez également vérifier que les connexions sont correctes dans votre fichier storyboard / xib, sinon les valeurs seront
nil
au moment de l'exécution, et donc se bloqueront lorsqu'elles seront implicitement déballées . Lors de la réparation des connexions, essayez de supprimer les lignes de code qui définissent vos prises, puis reconnectez-les.Quand devrais-je forcer le déballage d'une option?
Déballage forcé explicite
En règle générale, vous ne devez jamais forcer explicitement le déballage d'une option avec l'
!
opérateur. Il peut y avoir des cas où l'utilisation!
est acceptable - mais vous ne devriez jamais l'utiliser que si vous êtes sûr à 100% que l'option contient une valeur.Bien qu'il puisse y avoir une occasion où vous pouvez utiliser le dépliage forcé, comme vous le savez pour un fait qu'une option contient une valeur - il n'y a pas un seul endroit où vous ne pouvez pas déballer en toute sécurité cette option à la place.
Options optionnelles implicitement déballées
Ces variables sont conçues pour que vous puissiez reporter leur affectation à plus tard dans votre code. Il est de votre responsabilité de vous assurer qu'ils ont une valeur avant d'y accéder. Cependant, parce qu'ils impliquent un déballage forcé, ils sont toujours intrinsèquement dangereux - car ils supposent que votre valeur n'est pas nulle, même si l'attribution de zéro est valide.
Vous ne devez utiliser les options implicitement déballées qu'en dernier recours . Si vous pouvez utiliser une variable différée ou fournir une valeur par défaut pour une variable - vous devez le faire au lieu d'utiliser une option implicitement non enveloppée.
Cependant, il existe quelques scénarios où les options implicitement déballées sont bénéfiques , et vous pouvez toujours utiliser différentes façons de les déballer en toute sécurité comme indiqué ci-dessous - mais vous devez toujours les utiliser avec la prudence requise.
Comment puis-je traiter en toute sécurité avec les options?
La manière la plus simple de vérifier si une option contient une valeur est de la comparer à
nil
.Cependant, 99,9% du temps lorsque vous travaillez avec des options, vous souhaiterez réellement accéder à la valeur qu'il contient, si elle en contient une. Pour ce faire, vous pouvez utiliser la liaison facultative .
Reliure optionnelle
La liaison facultative vous permet de vérifier si une option contient une valeur - et vous permet d'affecter la valeur non encapsulée à une nouvelle variable ou constante. Il utilise la syntaxe
if let x = anOptional {...}
ouif var x = anOptional {...}
, selon que vous devez modifier la valeur de la nouvelle variable après l'avoir liée.Par exemple:
Ce que cela signifie, c'est d'abord de vérifier que l'option contient une valeur. Si tel est le cas , la valeur 'unfrapped' est affectée à une nouvelle variable (
number
) - que vous pouvez ensuite utiliser librement comme si elle n'était pas facultative. Si l'option facultative 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 instructions par une virgule. L'instruction réussira si toutes les options ont été déballées.
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.
Le seul inconvénient de l'utilisation de la liaison facultative dans une instruction if est que vous ne pouvez accéder à la valeur non encapsulée que dans la portée de l'instruction. Si vous avez besoin d'accéder à la valeur en dehors de la portée de l'instruction, vous pouvez utiliser une instruction guard .
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 syntaxe
guard condition else {...}
.Donc, pour les utiliser avec une liaison facultative, vous pouvez le faire:
(Notez que dans le corps du garde, vous devez utiliser l'une des instructions de transfert de contrôle afin de quitter la portée du code en cours d'exécution).
Si
anOptionalInt
contient une valeur, elle sera dépliée et affectée à la nouvellenumber
constante. Le code après le gardien continuera alors à s'exécuter. S'il ne contient pas de valeur - le gardien exécutera le code entre crochets, 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 enveloppée est maintenant disponible à utiliser 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.
Par exemple:
Les gardes prennent également en charge les mêmes astuces que celles prises en charge par l'instruction if, telles que le déballage de plusieurs options en même temps et l'utilisation de la
where
clause.Que vous utilisiez une déclaration si ou la garde dépend entièrement de savoir si un code d'avenir nécessite l'option pour contenir une valeur.
Opérateur de coalescence nul
L' opérateur de coalescence nul est une version abrégée astucieuse de l' opérateur conditionnel ternaire , principalement conçu pour convertir les options en options. Il a la syntaxe
a ?? b
, oùa
est un type facultatif etb
est le même type quea
(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, revenez à lab
place ». Par exemple, vous pouvez l'utiliser comme ceci:Cela définira une
number
constante deInt
type, qui contiendra la valeur deanOptionalInt
, si elle contient une valeur, ou0
autrement.C'est juste un raccourci pour:
Chaînage en option
Vous pouvez utiliser le chaînage facultatif pour appeler une méthode ou accéder à une propriété sur un facultatif. Cela se fait simplement en suffixant le nom de la variable avec a
?
lors de son utilisation.Par exemple, disons que nous avons une variable
foo
, de type uneFoo
instance facultative .Si nous voulions appeler une méthode
foo
qui ne retourne rien, nous pouvons simplement faire:Si
foo
contient une valeur, cette méthode sera appelée dessus. Si ce n'est pas le cas, rien de mauvais ne se produira - le code continuera simplement à s'exécuter.(Il s'agit d'un comportement similaire à l'envoi de messages
nil
dans Objective-C)Cela peut donc également être utilisé pour définir des propriétés ainsi que des méthodes d'appel. Par exemple:
Encore une fois, de mauvais ne se passera rien ici si
foo
estnil
. Votre code continuera simplement à s'exécuter.Une autre astuce intéressante 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 à
nil
.(Cela est dû au fait qu'une valeur facultative renvoie
Void?
plutôt qu'uneVoid
méthode qui ne renvoie rien)Par exemple:
Cependant, les choses deviennent un peu plus délicates lorsque vous essayez d'accéder à des propriétés ou d'appeler des méthodes qui renvoient une valeur. Parce que
foo
c'est facultatif, tout ce qui en sera retourné sera également facultatif. Pour résoudre ce problème, vous pouvez soit déballer les options qui sont renvoyées à l'aide de l'une des méthodes ci-dessus - soit déballerfoo
lui-même avant d'accéder aux méthodes ou d'appeler des méthodes qui renvoient des valeurs.De plus, comme son nom l'indique, vous pouvez «enchaîner» ces déclarations ensemble. Cela signifie que si
foo
a une propriété facultativebaz
, qui a une propriétéqux
- vous pouvez écrire ce qui suit:Encore une fois, car
foo
etbaz
sont facultatifs, la valeur renvoyée parqux
sera toujours facultative, qu'ellequx
soit facultative.map
etflatMap
Une fonctionnalité souvent sous-utilisée avec les options est la possibilité d'utiliser les fonctions
map
etflatMap
. Ceux-ci vous permettent d'appliquer des transformations non facultatives aux variables facultatives. Si une option a une valeur, vous pouvez lui appliquer une transformation donnée. S'il n'a pas de valeur, il resteranil
.Par exemple, supposons que vous ayez une chaîne facultative:
En lui appliquant la
map
fonction - nous pouvons utiliser lastringByAppendingString
fonction afin de la concaténer à une autre chaîne.Parce que
stringByAppendingString
prend un argument de chaîne non facultatif, nous ne pouvons pas saisir directement notre chaîne facultative. Cependant, en utilisantmap
, nous pouvons utiliser allowstringByAppendingString
à utiliser sianOptionalString
a une valeur.Par exemple:
Cependant, si
anOptionalString
n'a pas de valeur,map
reviendranil
. Par exemple:flatMap
fonctionne de manière similaire àmap
, sauf qu'il vous permet de renvoyer une autre option depuis le corps de fermeture. Cela signifie que vous pouvez saisir une option dans un processus qui nécessite une entrée non optionnelle, mais vous pouvez également générer une option elle-même.try!
Le système de gestion des erreurs de Swift peut être utilisé en toute sécurité avec Do-Try-Catch :
Si
someThrowingFunc()
jette une erreur, l'erreur sera capturée en toute sécurité dans lecatch
bloc.La
error
constante que vous voyez dans lecatch
bloc n'a pas été déclarée par nous - elle est automatiquement générée parcatch
.Vous pouvez également
error
vous déclarer , il a l'avantage de pouvoir le caster dans un format utile, par exemple:L'utilisation de
try
cette façon est la bonne façon d'essayer, de détecter et de gérer les erreurs provenant des fonctions de lancement.Il y a aussi
try?
qui absorbe l'erreur:Mais le système de gestion des erreurs de Swift fournit également un moyen de "forcer l'essai" avec
try!
:Les concepts expliqués dans cet article s'appliquent également ici: si une erreur est levée, l'application se bloque.
Vous ne devez l'utiliser que
try!
si vous pouvez prouver que son résultat n'échouera jamais dans votre contexte - et cela est très rare.La plupart du temps, vous utiliserez le système Do-Try-Catch complet - et le système optionnel
try?
, dans les rares cas où la gestion de l'erreur n'est pas importante.Ressources
la source
compactMap()
place deflatMap()
.Réponse TL; DR
À quelques exceptions près , cette règle est d'or:
Évitez d'utiliser
!
Déclarez la variable optional (
?
), et non les options implicitement non enveloppées (IUO) (!
)En d'autres termes, utilisez plutôt:
var nameOfDaughter: String?
Au lieu de:
var nameOfDaughter: String!
Déballez la variable facultative à l'aide de
if let
ouguard let
Soit dérouler la variable comme ceci:
Ou comme ça:
Cette réponse était censée être concise, pour une compréhension complète, lire la réponse acceptée
Ressources
la source
Cette question revient tout le temps sur SO. C'est l'une des premières choses avec lesquelles les nouveaux développeurs Swift ont du mal.
Contexte:
Swift utilise le concept d '«options» pour traiter les valeurs qui pourraient contenir une valeur ou non. Dans d'autres langages comme C, vous pouvez stocker une valeur de 0 dans une variable pour indiquer qu'elle ne contient aucune valeur. Mais que faire si 0 est une valeur valide? Ensuite, vous pourriez utiliser -1. Et si -1 est une valeur valide? Etc.
Les options Swift vous permettent de configurer une variable de n'importe quel type pour contenir soit une valeur valide, soit aucune valeur.
Vous mettez un point d'interrogation après le type lorsque vous déclarez une variable à signifier (type x, ou aucune valeur).
Une option est en fait un conteneur qui contient soit une variable d'un type donné, soit rien.
Une option doit être "déballée" afin de récupérer la valeur à l'intérieur.
Le "!" L'opérateur est un opérateur "déplier de force". Il dit "faites-moi confiance. Je sais ce que je fais. Je garantis que lorsque ce code s'exécutera, la variable ne contiendra pas nil." Si vous vous trompez, vous vous plantez.
À moins que vous ne sachiez vraiment ce que vous faites, évitez le "!" forcer l'opérateur de déballage. C'est probablement la plus grande source de plantages pour les programmeurs Swift débutants.
Comment gérer les options:
Il existe de nombreuses autres façons de gérer les options qui sont plus sûres. En voici quelques unes (liste non exhaustive)
Vous pouvez utiliser "liaison facultative" ou "si laissé" pour dire "si cette option contient une valeur, enregistrez cette valeur dans une nouvelle variable non facultative. Si l'option ne contient pas de valeur, ignorez le corps de cette instruction if ".
Voici un exemple de liaison optionnelle avec notre
foo
option:Notez que la variable que vous définissez lorsque vous utilisez le biding facultatif existe uniquement (est uniquement "dans la portée") dans le corps de l'instruction if.
Alternativement, vous pouvez utiliser une instruction guard, qui vous permet de quitter votre fonction si la variable est nulle:
Des instructions Guard ont été ajoutées dans Swift 2. Guard vous permet de préserver le «chemin d'or» dans votre code et d'éviter des niveaux toujours croissants de if imbriqués qui résultent parfois de l'utilisation de la liaison facultative «if let».
Il existe également une construction appelée "opérateur de coalescence nul". Il prend la forme "optionnelle_var ?? remplacement_val". Il renvoie une variable non facultative du même type que les données contenues dans l'option. Si l'option facultative contient nil, elle renvoie la valeur de l'expression après le "??" symbole.
Vous pouvez donc utiliser du code comme celui-ci:
Vous pouvez également utiliser la gestion des erreurs try / catch ou guard, mais généralement l'une des autres techniques ci-dessus est plus propre.
ÉDITER:
Un autre piège légèrement plus subtil avec les options est "les options implicitement déballées. Lorsque nous déclarons foo, nous pouvons dire:
Dans ce cas, foo est toujours facultatif, mais vous n'avez pas à le déballer pour le référencer. Cela signifie que chaque fois que vous essayez de référencer foo, vous vous plantez s'il est nul.
Donc, ce code:
Crashera en référence à la propriété capitalizedString de foo même si nous ne sommes pas en train de déplier foo. l'impression semble bien, mais ce n'est pas le cas.
Vous devez donc être très prudent avec les options implicitement déballées. (et peut-être même les éviter complètement jusqu'à ce que vous ayez une bonne compréhension des options.)
Conclusion: lorsque vous apprenez Swift pour la première fois, faites semblant de "!" le caractère ne fait pas partie de la langue. Cela risque de vous causer des ennuis.
la source
guard
clauses. Il n'y a rien dans l'utilisation d'if var
une construction aussi valide queif let
. Il n'y a rien sur leswhere
clauses qui, à mon avis, mérite d'être mentionné lorsque nous parlons deif let
liaison (cela supprime toute une couche d'imbrication dans de nombreux cas). Il n'y a rien à propos du chaînage optionnel.Étant donné que les réponses ci-dessus expliquent clairement comment jouer en toute sécurité avec les options. Je vais essayer d'expliquer ce que les options sont vraiment rapides.
Une autre façon de déclarer une variable facultative est
var i : Optional<Int>
Et le type facultatif n'est rien d'autre qu'une énumération avec deux cas, c.-à-d.
Donc, pour affecter un zéro à notre variable «i». On peut faire
var i = Optional<Int>.none
ou assigner une valeur, on va passer de la valeurvar i = Optional<Int>.some(28)
Selon Swift, «néant» est l'absence de valeur. Et pour créer une instance initialisée avec
nil
Nous devons nous conformer à un protocole appeléExpressibleByNilLiteral
et génial si vous l'avez deviné, seulement seOptionals
conformerExpressibleByNilLiteral
et se conformer à d'autres types est déconseillé.ExpressibleByNilLiteral
a une seule méthode appeléeinit(nilLiteral:)
qui initialise une instance avec nil. Vous n'appelez généralement pas cette méthode et, selon la documentation rapide, il est déconseillé d'appeler cet initialiseur directement car le compilateur l'appelle chaque fois que vous initialisez un type facultatif avec unnil
littéral.Même moi, je dois envelopper (sans jeu de mots) ma tête autour des options : D Happy Swfting All .
la source
Tout d'abord, vous devez savoir ce qu'est une valeur facultative. Vous pouvez accéder au langage de programmation Swift pour plus de détails.
Deuxièmement, vous devez savoir que la valeur facultative a deux statuts. L'un est la valeur complète et l'autre est une valeur nulle. Donc, avant d'implémenter une valeur facultative, vous devez vérifier son état.
Vous pouvez utiliser
if let ...
ouguard let ... else
et ainsi de suite.D'une autre manière, si vous ne souhaitez pas vérifier l'état de la variable avant votre implémentation, vous pouvez également l'utiliser à la
var buildingName = buildingName ?? "buildingName"
place.la source
J'ai eu cette erreur une fois lorsque j'essayais de définir mes valeurs de sortie à partir de la méthode de préparation pour la séquence comme suit:
Ensuite, j'ai découvert que je ne peux pas définir les valeurs des sorties du contrôleur de destination car le contrôleur n'a pas encore été chargé ou initialisé.
Je l'ai donc résolu de cette façon:
Contrôleur de destination:
J'espère que cette réponse aide n'importe qui là-bas avec le même problème que j'ai trouvé que la réponse marquée est une excellente ressource pour la compréhension des options et comment ils fonctionnent, mais n'a pas abordé le problème lui-même directement.
la source
updateView
le contrôleur de destination;)updateView
dans le contrôleur de destination n'est pas nécessaire dans ce cas car j'utilise laname
variable pour définir lenameLabel.text
dans leviewDidLoad
. Mais si nous faisions beaucoup de configuration, il serait certainement préférable de créer une autre fonction et de l'appeler à partir deviewDidLoad
.Fondamentalement, vous avez essayé d'utiliser une valeur nulle dans des endroits où Swift n'autorise que des valeurs non nulles, en disant au compilateur de vous faire confiance qu'il n'y aura jamais de valeur nulle, permettant ainsi à votre application de compiler.
Il existe plusieurs scénarios qui conduisent à ce type d'erreur fatale:
déballages forcés:
Si
someVariable
est nul, alors vous obtiendrez un plantage. En effectuant un déballement forcé, vous avez déplacé la responsabilité de vérification nulle du compilateur vers vous, essentiellement en faisant un déballement forcé, vous garantissez au compilateur que vous n'aurez jamais de valeurs nulles là-bas. Et devinez ce qui se passe si en quelque sorte une valeur nulle se termine parsomeVariable
?Solution? Utilisez la liaison facultative (alias if-let), faites le traitement des variables là-bas:
lancers forcés (vers le bas):
Ici, en forçant, vous dites au compilateur de ne plus vous inquiéter, car vous aurez toujours une
Rectangle
instance là-bas. Et tant que cela tient, vous n'avez pas à vous inquiéter. Les problèmes commencent lorsque vous ou vos collègues du projet commencez à faire circuler des valeurs non rectangulaires.Solution? Utilisez la liaison facultative (alias if-let), faites le traitement des variables là-bas:
Options optionnelles implicitement déballées. Supposons que vous ayez la définition de classe suivante:
Maintenant, si personne ne se trompe avec le
name
propriété en la définissant surnil
, cela fonctionne comme prévu, mais s'ilUser
est initialisé à partir d'un JSON qui n'a pas laname
clé, vous obtenez l'erreur fatale lorsque vous essayez d'utiliser la propriété.Solution? Ne les utilisez pas :) À moins que vous ne soyez sûr à 102% que la propriété aura toujours une valeur non nulle au moment où elle doit être utilisée. Dans la plupart des cas, la conversion en option ou non optionnelle fonctionnera. Si vous le rendez non facultatif, le compilateur vous aidera également en indiquant les chemins de code que vous avez manqués en donnant une valeur à cette propriété.
Prises non connectées ou pas encore connectées. Il s'agit d'un cas particulier du scénario # 3. En gros, vous avez une classe chargée par XIB que vous souhaitez utiliser.
Maintenant, si vous avez manqué de connecter la prise à partir de l'éditeur XIB, l'application se bloquera dès que vous voudrez utiliser la prise. Solution? Assurez-vous que toutes les prises sont connectées. Ou utilisez l'
?
opérateur sur eux:emailTextField?.text = "[email protected]"
. Ou déclarez la sortie comme facultative, bien que dans ce cas, le compilateur vous obligera à la dérouler sur tout le code.Valeurs provenant d'Objective-C, et qui n'ont pas d'annotations de nullité. Supposons que nous avons la classe Objective-C suivante:
Maintenant, si aucune annotation de nullité n'est spécifiée (explicitement ou via
NS_ASSUME_NONNULL_BEGIN
/NS_ASSUME_NONNULL_END
), laname
propriété sera importée dans Swift sous la formeString!
(une IUO - implicitement déballée en option). Dès qu'un code rapide voudra utiliser la valeur, il se bloquera s'ilname
est nul.Solution? Ajoutez des annotations de nullité à votre code Objective-C. Attention cependant, le compilateur Objective-C est un peu permissif en ce qui concerne la nullité, vous pourriez vous retrouver avec des valeurs nulles, même si vous les avez explicitement marquées comme
nonnull
.la source
C'est plus un commentaire important et c'est pourquoi les options implicitement déballées peuvent être trompeuses quand il s'agit de déboguer
nil
valeurs.Pensez au code suivant: Il se compile sans erreurs / avertissements:
Pourtant, lors de l'exécution, il donne l'erreur suivante: Erreur fatale: trouvé de manière inattendue nil lors du déballage d'une valeur facultative
Pouvez-vous me dire quel objet est
nil
?Tu ne peux pas!
Le code complet serait:
En bref, en utilisant,
var address : Address!
vous cachez la possibilité qu'une variable puisse provenirnil
d'autres lecteurs. Et quand ça tombe en panne, vous vous dites "qu'est-ce qui se passe ?!address
n'est pas optionnel, alors pourquoi je plante?!.Il vaut donc mieux écrire comme tel:
Pouvez-vous maintenant me dire de quel objet il s'agissait
nil
?Cette fois, le code vous a été rendu plus clair. Vous pouvez rationaliser et penser que c'est probablement le
address
paramètre qui a été déplié avec force.Le code complet serait:
la source
Les erreurs
EXC_BAD_INSTRUCTION
etfatal error: unexpectedly found nil while implicitly unwrapping an Optional value
apparaissent le plus lorsque vous avez déclaré un@IBOutlet
, mais pas connecté au storyboard .Vous devriez également vous renseigner sur le fonctionnement des options , mentionné dans d'autres réponses, mais c'est la seule fois qui me semble le plus souvent.
la source
@IBOutlet
cause de cette erreur ne devrait-elle pas avoir l' erreur fatale: trouvé de manière inattendue nul alors que vous dépliez implicitement une version de valeur facultative de l'erreur?Si vous obtenez cette erreur dans CollectionView, essayez de créer également un fichier CustomCell et un fichier xib personnalisé.
ajoutez ce code dans ViewDidLoad () à mainVC.
la source
J'ai rencontré cette erreur lors de la transition d'un contrôleur de vue de table à un contrôleur de vue, car j'avais oublié de spécifier le nom de classe personnalisé pour le contrôleur de vue dans le storyboard principal.
Quelque chose de simple qui mérite d'être vérifié si tout le reste semble correct
la source