web-dev-qa-db-ja.com

致命的なエラー:Optional値の展開中に予期せずnilが見つかりました

私はSwiftでUICollectionViewを使用していましたが、セルのラベルのテキストを変更しようとするとわかります。

    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
}

誰もがこれについて知っていますか?

Screenshot for warning on Console

124
rulilg

ほぼ確実に、あなたの再利用識別子"title"は正しくありません。

dequeueReusableCellWithIdentifierUITableView.hメソッドのシグネチャから、戻り型が暗黙的にラップされていないオプションであることがわかります。

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

それはAnyObjectの後の感嘆符によって決まります。

    AnyObject!

それで、最初に考慮すべきことは、「暗黙的にラップされていないオプション」とは何ですか?

Swift Programming Language は次のように教えてくれます。

オプションの値が最初に設定された後、オプションの値が常に値を持つことがプログラムの構造から明らかになることがあります。このような場合は、アクセスするたびにオプションの値を確認して展開する必要がなくなります。これは、常に値があると安全に想定できるためです。

これらの種類のオプションは、暗黙的にラップされていないオプションとして定義されています。オプションにするタイプの後に疑問符(String?)ではなく感嘆符(String!)を配置することによって、暗黙的にラップされていないオプションを作成します。

したがって、基本的には、ある時点でゼロになっていた可能性がありますが、ある時点からそれが再びゼロになることはありません。そのため、ラップされていない値としてそれを取り入れることによって、私たちは自分自身をいくらか面倒にしています。

この場合、dequeueReusableCellWithIdentifierがそのような値を返すことは意味があります。指定された識別子は、再利用のためにセルを登録するためにすでに使用されている必要があります。誤った識別子を指定すると、デキューはそれを見つけることができません。これは致命的なエラーです。アプリがクラッシュし、Consoleの出力には次のように表示されます。

fatal error: unexpectedly found nil while unwrapping an Optional value

結論:.storyboard、Xib、またはコードで指定されているセルの再利用識別子を確認し、デキュー時に正しいことを確認してください。

79
Max MacLeod

cell.labelTitleステートメントでif letを安全にアンラップすることでクラッシュが発生しないようにすることができます。

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

それでもなぜあなたがそこにnil値を得ているのかを見るためには、まだいくらかのデバッグをしなければならないでしょう。

101
Connor

セルがself.collectionView.registerClass(cellClass: AnyClass?, forCellWithReuseIdentifier identifier: String)に登録されているか確認してください。もしそうなら、そのコード行を削除します。

詳細については、この回答を参照してください。 UICollectionViewCellのアウトレットがnilなのはなぜですか?

「ストーリーボードを使用している場合は、これを呼び出したくはありません。ストーリーボードの内容は上書きされます。」

25
Ron Fessler

私はそれがバグか何かであることを知りませんが、あなたがカスタムセルを使うとき、あなたのラベルと他のUIは自動的に初期化されません。あなたはUICollectionViewControllerクラスでこれを試すべきです。それは私のために働きました。

override func viewDidLoad() {
    super.viewDidLoad()

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

この行を置き換えますcell.labelTitle.text = "This is a title"
cell.labelTitle?.text = "This is a title"

12
iOS Developer

私はUILabelにアクセスしようとしたときに私は彼のエラーを得ました。 StoryboardでUILabelIBOutletに接続するのを忘れたため、このエラーでアプリがクラッシュしました。

6
Pruthvid

私もこの問題を抱えていて、問題はView Controllerにありました。私はあなたのアプリケーションがどのように構成されているかわからないので、私が見つけたものを説明します。私はxcodeとコーディングにかなり慣れていないので、私と一緒に負担してください。

UILabelのテキストをプログラムで変更しようとしていました。 「self.mylabel.text」を使用しても、同じクラスに別のView Controllerを追加して、そのラベルも含めないようにするまでは、うまくいきました。それは私があなたが見ているというエラーを得たときです。同じUILabelを追加してそれをその追加のView Controllerに接続すると、エラーは消えました。

つまり、Swiftでは、同じクラスに割り当てられているすべてのView Controllerが、そこにあるコードを参照する必要があります。そうしないと、エラーが発生します。コードが異なる2つの異なるView Controllerがある場合は、それらを異なるクラスに割り当てます。これは私のために働いたし、うまくいけばあなたがやっていることに適用されます。

3
ClareHuxtable

致命的エラー:Optional値の展開中に予期せずnilが見つかりました

  1. このエラーが接続されていないuielementオブジェクトの使用法になる可能性があるのでIBOutletコレクションを確認してください。

:)それが何人かの苦労した人々のために役立つことを願っています。

2
Kishore Kumar

私はXcode 7.3で同じ問題を抱えていました。私の解決策は、自分のセルに正しい再利用識別子があることを確認することでした。 テーブルビューセクションの下で、テーブルビューセルを対応する識別子に設定します。プログラムで使用している名前が一致することを確認してください

1
ekeith

Nil Coalescing Operatorも使用できます。

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

私はこれを解決する方法を探してみました。ここで言及しているように、私の問題だけがUITableViewCellではなくUICollectionViewに関連していました。

まず第一に、iOS開発には初めてのことです。新品のように、ここに座って私の最初のチュートリアルを通り抜けようとしているので、私のWordを何のためにも取らないでください。 (動作しない限り)

私がcell.detailTextLabel.textを参照していない - 私がフォローしていたチュートリアルビデオを見直した後、私は何も見逃していたようには見えなかった。だから私はUITableViewCellのヘッダファイルを入力してこれを見つけた。

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

だから私はそれが言うことに気づいた(そして現在のスタイルは詳細ラベルをサポートしています) - まあ、カスタムスタイルはデフォルトではそこにdetailLabelを持っていません。ストーリーボードのセルのスタイルを変更するだけで、すべて問題ありませんでした。

あなたのレーベルは常にそこにあるべきだと思いますか?

それで、あなたの次のコナーのアドバイス、それが基本的に、そのラベルが利用可能であるならばそれを使うなら、それを使ってください。スタイルが正しく設定されており、再利用識別子がストーリーボードで設定されているものと一致する場合は、複数のカスタムセルを使用しない限り、このチェックを行う必要はありません。

1
Christer

ここでも同じメッセージですが、原因は異なります。私はセグエを押し上げたUIBarButtonを持っていました。セグエには識別子がありませんでした。

0
David DelMonte

私は同じ問題を抱えていました、そして、その理由は私が間違った名前でUIImageをロードしようとしていたからです。 .setImage(UIImage(named: "-name-"呼び出しを再確認して、名前が正しいことを確認してください。

0
Hugo Sequeira