web-dev-qa-db-fra.com

Erreur fatale: erreur inattendue lors du déroulement d'une valeur facultative

J'utilisais une UICollectionView dans Swift, mais j'obtiens lorsque j'essaie de modifier le texte de l'étiquette de la cellule.

    func collectionView(collectionView: UICollectionView!, numberOfItemsInSection section: Int) -> Int
{
    return 5
}

func collectionView(collectionView: UICollectionView!, cellForItemAtIndexPath indexPath: NSIndexPath!) -> UICollectionViewCell!
{
    var cell = collectionView.dequeueReusableCellWithReuseIdentifier("title", forIndexPath: indexPath) as TitleCollectionViewCell
    // Next line: fatal error: unexpectedly found nil while unwrapping an Optional value
    cell.labelTitle.text = "This is a title"
    return cell
}

Est-ce que quelqu'un sait à propos de cela?

 Screenshot for warning on Console

120
rulilg

Il est presque certain que votre identifiant de réutilisation "title" est incorrect.

Nous pouvons voir dans la signature de la méthode UITableView.h de dequeueReusableCellWithIdentifier que le type de retour est un implicitement non enveloppé, facultatif} [:

func dequeueReusableCellWithIdentifier(identifier: String!) -> AnyObject! // Used by the delegate to acquire an already allocated cell, in lieu of allocating a new one.

C'est déterminé par le point d'exclamation après AnyObject:

    AnyObject!

Alors, la première chose à considérer est, qu'est-ce qu'un "Implicitly Unwrapped Optionnel"?

Le langage de programmation Swift nous dit:

Parfois, il ressort clairement de la structure d’un programme qu’un testament optionnel toujours avoir une valeur, après que cette valeur est définie en premier. Dans ces cas, il est utile pour supprimer la nécessité de vérifier et de dérouler la valeur facultative chaque fois que vous y accédez, car on peut supposer en toute sécurité avoir un valoriser tout le temps.

Ces types d’options sont définis comme implicitement non emballés les optionnels. Vous écrivez un optionnel implicitement non emballé en plaçant un point d'exclamation (String!) plutôt qu'un point d'interrogation (String?) après le type que vous voulez rendre facultatif.

Donc, en gros, quelque chose qui aurait pu être nul à un moment donné, mais qui à partir de ce moment n'est plus jamais nul. Nous nous épargnons donc quelques ennuis en le prenant comme valeur non emballée.

Dans ce cas, il est logique que dequeueReusableCellWithIdentifier renvoie une telle valeur. L'identifiant fourni doit déjà avoir été utilisé pour enregistrer la cellule en vue d'une réutilisation. Entrez un identifiant incorrect, la file d'attente ne peut pas le trouver et le moteur d'exécution renvoie un zéro qui ne devrait jamais se produire. C'est une erreur fatale, l'application se bloque et la sortie de la console donne:

fatal error: unexpectedly found nil while unwrapping an Optional value

Ligne inférieure: vérifiez votre identifiant de réutilisation de cellule spécifié dans le .storyboard, Xib ou dans le code, et assurez-vous qu'il est correct lors de la mise en file d'attente. 

78
Max MacLeod

Vous pouvez empêcher le blocage en décompressant cell.labelTitle en toute sécurité avec une instruction if let

if let label = cell.labelTitle{
    label.text = "This is a title"
}

Vous devrez quand même faire du débogage pour comprendre pourquoi vous obtenez une valeur nulle dans ce cas.

101
Connor

Vérifiez si la cellule est en cours d'enregistrement avec self.collectionView.registerClass(cellClass: AnyClass?, forCellWithReuseIdentifier identifier: String). Si tel est le cas, supprimez cette ligne de code.

Voir cette réponse pour plus d’informations: Pourquoi la sortie d’UICollectionViewCell est-elle nulle?

"Si vous utilisez un storyboard, vous ne voulez pas appeler cela. Cela écrasera ce que vous avez dans votre storyboard."

25
Ron Fessler

Je ne sais pas si c'est un bogue ou quelque chose du genre, mais vos étiquettes et autres interfaces utilisateur ne sont pas initialisées automatiquement lorsque vous utilisez une cellule personnalisée Vous devriez essayer ceci dans votre classe UICollectionViewController. Cela a fonctionné pour moi.

override func viewDidLoad() {
    super.viewDidLoad()

    let nib = UINib(nibName: "<WhateverYourNibName>", bundle: nil)
    self.collectionView.registerNib(nib, forCellReuseIdentifier: "title")
}
19
greeninaqua

Remplacez cette ligne cell.labelTitle.text = "This is a title"
avec cell.labelTitle?.text = "This is a title" 

12
iOS Developer

J'ai eu son erreur quand j'essayais d'accéder à UILabel. J'ai oublié de connecter UILabel à IBOutlet dans Storyboard, ce qui provoquait le blocage de l'application avec cette erreur!

6
Pruthvid

J'avais ce problème aussi et le problème était dans les contrôleurs de vue. Je ne suis pas sûr de la structure de votre demande, je vais donc expliquer ce que j'ai trouvé. Je suis assez nouveau en xcode et en codage, alors supportez-moi.

J'essayais de modifier par programme le texte sur un UILabel. L'utilisation de "self.mylabel.text" a bien fonctionné jusqu'à ce que j'ajoute un autre contrôleur de vue sous la même classe qui n'inclut pas également cette étiquette. C'est quand j'ai eu l'erreur que vous voyez. Lorsque j'ai ajouté le même UILabel et que je l'ai connecté à ce contrôleur de vue supplémentaire, l'erreur a disparu.

En bref, il semble que dans Swift, tous les contrôleurs de vue affectés à la même classe doivent référencer le code que vous avez dedans, sinon vous obtiendrez une erreur. Si vous avez deux contrôleurs de vue différents avec un code différent, affectez-les à des classes différentes. Cela a fonctionné pour moi et, espérons-le, s'applique à ce que vous faites.

3
ClareHuxtable

erreur fatale: erreur inattendue lors du déroulement d'une valeur facultative

  1. Vérifiez la collection IBOutlet, car cette erreur aura la possibilité d'utiliser des objets non connectés. 

:) espère que cela aidera certaines personnes en difficulté. 

2
Kishore Kumar

J'ai eu le même problème sur Xcode 7.3. Ma solution était de m'assurer que mes cellules avaient les correctifs identifiants de réutilisation . Dans la section Vue de la table , définissez la cellule Vue de la table sur le nom d'identifiant correspondant que vous utilisez dans le programme, Assurez-vous qu'ils correspondent

1
ekeith

Nil Coalescing Operator peut également être utilisé.

rowName = rowName != nil ?rowName!.stringFromCamelCase():""
1
Abhijeet

J'ai cherché une solution à ce problème moi-même. seul mon problème était lié à UITableViewCell et non à UICollectionView en tant que votre mention ici. 

Tout d'abord, je suis nouveau dans le développement iOS. comme tout neuf, assis ici à essayer d’obtenir mon premier tutoriel, alors ne prenez pas ma parole pour quoi que ce soit. (sauf si cela fonctionne;))

J'obtenais une référence nulle à cell.detailTextLabel.text - Après avoir revu le didacticiel vidéo que je suivais, il ne semblait pas que j'avais rien manqué. J'ai donc entré le fichier d'en-tête pour UITableViewCell et l'ai trouvé. 

var detailTextLabel: UILabel! { get } // default is nil. label will be created if necessary (and the current style supports a detail label).

Donc, j'ai remarqué qu'il est écrit (et que le style actuel prend en charge une étiquette de détail) - Eh bien, le style personnalisé n'a pas d'étiquette de détail par défaut. donc je devais juste changer le style de la cellule dans le Storyboard, et tout allait bien. 

Je suppose que votre étiquette devrait toujours être là?

Donc, si votre conseil suivant de connor`s, cela signifie fondamentalement, si cette étiquette est disponible, alors utilisez-le. Si votre style est correctement configuré et que l'identifiant de réutilisation correspond à celui défini dans le Storyboard, vous ne devriez pas avoir à effectuer cette vérification, sauf si vous utilisez plus d'une cellule personnalisée.

1
Christer

Même message ici, mais avec une cause différente. J'ai eu une UIBarButton qui a poussé une transition. La séquence n'avait pas d'identifiant.

0
David DelMonte

J'avais le même problème et la raison en était que j'essayais de charger un UIImage avec un mauvais nom. Vérifiez deux fois les appels .setImage(UIImage(named: "-name-" et assurez-vous que le nom est correct.

0
Hugo Sequeira