「致命的なエラー:オプションの値のアンラップ中に予期せずnilが見つかりました」とはどういう意味ですか?

429
pkamb 2015-08-24 09:10.

私のSwiftプログラムはEXC_BAD_INSTRUCTION、次のいずれかの同様のエラーでクラッシュします。このエラーはどういう意味ですか、どうすれば修正できますか?

致命的なエラー:オプション値のアンラップ中に予期せずnilが見つかりました

または

致命的なエラー:オプションの値を暗黙的にアンラップしているときに、予期せずnilが見つかりました


この投稿は、「予期せず見つかったnil」の問題に対する回答を収集することを目的としているため、それらが散在して見つけにくいものではありません。独自の回答を追加するか、既存のWiki回答を編集してください。

11 answers

685
Hamish 2015-08-24 09:10.

この答えは「コミュニティWiki」の投稿とは何ですか?です。改善できると思われる場合は、お気軽に編集してください。

背景:オプションとは何ですか?

Swiftでは、Optional<Wrapped>オプションタイプです。元の(「ラップされた」)タイプの任意の値を含めることも、まったく値を含めない(特別な値nil)こともできます。オプションの値は、使用する前にラップを解除する必要があります。

オプションはジェネリック型です。これは、Optional<Int>Optional<String>が別個のであることを意味し<>ます。内部の型はラップ型と呼ばれます。内部的には、Optionalは2つのケースを持つ列挙型です:.some(Wrapped).none、ここで、はと.none同等nilです。

オプションは、名前付きタイプを使用して宣言するOptional<T>か、(最も一般的には)?接尾辞付きの省略形として宣言できます。

var anInt: Int = 42
var anOptionalInt: Int? = 42
var anotherOptionalInt: Int?  // `nil` is the default when no value is provided
var aVerboseOptionalInt: Optional<Int>  // equivalent to `Int?`

anOptionalInt = nil // now this variable contains nil instead of an integer

オプションは、コードを記述しながら仮定を表現するためのシンプルでありながら強力なツールです。コンパイラーはこの情報を使用して、ユーザーが間違いを犯さないようにすることができます。スウィフトプログラミング言語

Swiftはタイプセーフな言語です。つまり、この言語は、コードで使用できる値のタイプを明確にするのに役立ちます。コードの一部にが必要なString場合、型安全性によりInt、誤ってコードを渡すことを防ぎます。同様に、型安全性は、オプションStringを必要とするコードにオプションを誤って渡すことを防ぎますString型安全性は、開発プロセスのできるだけ早い段階でエラーを見つけて修正するのに役立ちます。

いくつかの他のプログラミング言語も、ジェネリック持っているオプションの種類を:例えば、たぶんHaskellの、でオプション錆であり、オプションのC ++ 17インチ

オプションタイプのないプログラミング言語では、有効な値がないことを示すために特定の「センチネル」値がよく使用されます。たとえば、Objective-Cでは、nilnullポインタ)はオブジェクトがないことを表します。以下のようなプリミティブ型の場合はint、あなたが別の変数(のようないずれかの必要がありますので、ヌルポインタが、使用できないvalue: IntisValid: Bool)、または指定されたセンチネル値を(など-1INT_MIN)。これらのアプローチはisValid、番兵の値を確認したり確認したりするのを忘れがちなため、エラーが発生しやすくなります。また、特定の値が番兵として選択された場合、それは有効な値として扱われなくなることを意味します。

SwiftなどのオプションタイプはOptional、特別な個別のnil値を導入し(したがって、番兵の値を指定する必要がない)、強力な型システムを活用することでこれらの問題を解決します。これにより、コンパイラーは、必要に応じてnilを忘れずにチェックできます。


致命的なエラー:オプションの値をアンラップしているときに予期せずnilが見つかりました」というメッセージが表示されたのはなぜですか?

オプションの値にアクセスするには(オプションがある場合)、それをアンラップする必要があります。オプションの値は、安全または強制的にアンラップできます。オプションを強制的にアンラップし、値がなかった場合、プログラムは上記のメッセージでクラッシュします。

Xcodeは、コード行を強調表示することでクラッシュを表示します。この行で問題が発生します。

このクラッシュは、2種類の強制アンラップで発生する可能性があります。

1.明示的な強制アンラッピング

これは!、オプションのオペレーターで行われます。例えば:

let anOptionalString: String?
print(anOptionalString!) // <- CRASH

致命的なエラー:オプション値のアンラップ中に予期せずnilが見つかりました

以下のようanOptionalStringであるnilここで、あなたはそれアンラップ強制ライン上でクラッシュを取得します。

2.暗黙的にアンラップされたオプション

これらは、タイプの後では!なく、で定義され?ます。

var optionalDouble: Double!   // this value is implicitly unwrapped wherever it's used

これらのオプションには値が含まれていると見なされます。したがって、暗黙的にアンラップされたオプションにアクセスすると、自動的に強制的にアンラップされます。値が含まれていない場合、クラッシュします。

print(optionalDouble) // <- CRASH

致命的なエラー:オプションの値を暗黙的にアンラップしているときに、予期せずnilが見つかりました

クラッシュの原因となった変数を特定するために、押したままクリックして定義を表示すると、オプションのタイプが見つかります。

特に、IBOutletsは通常、暗黙的にラップ解除されたオプションです。これは、初期化、実行時にxibまたはストーリーボードがアウトレットをリンクするためです。したがって、ロードする前にアウトレットにアクセスしていないことを確認する必要があります。また、ストーリーボード/ xibファイルで接続が正しいことを確認する必要があります。そうしないと、値がnil実行時になり、暗黙的にアンラップされるとクラッシュします。 。接続を修正するときは、コンセントを定義するコード行を削除してから、再接続してみてください。


オプションのアンラップを強制する必要があるのはいつですか?

明示的な強制アンラッピング

原則として、!演算子を使用してオプションを明示的に強制的にアンラップしないでください。使用!が許容される場合もありますが、オプションに値が含まれていることが100%確実である場合にのみ使用する必要があります。

そこにいる間、あなたが知っているように、あなたはアンラップ力を使用することができる機会があり、実際のオプションに値が含まれていること-がない、単一のオプションの代わりに、あなたが安全にアンラップすることができない場所。

暗黙的にアンラップされたオプション

これらの変数は、コードの後半まで割り当てを延期できるように設計されています。アクセスする前に、それらに価値があることを確認するのはあなたの責任です。ただし、強制的なアンラップが含まれるため、nilの割り当ては有効ですが、値がnil以外であると想定しているため、本質的に安全ではありません。

最後の手段として、暗黙的にラップされていないオプションのみを使用する必要があります。遅延変数を使用できる場合、または変数デフォルト値指定できる場合は、暗黙的にアンラップされたオプションを使用する代わりに、そうする必要があります。

ただし、暗黙的にアンラップされたオプションが有益であるシナリオがいくつかあり、以下に示すように、それらを安全にアンラップするさまざまな方法を使用できますが、常に十分な注意を払って使用する必要があります。


オプションを安全に処理するにはどうすればよいですか?

オプションに値が含まれているかどうかを確認する最も簡単な方法は、それをと比較することnilです。

if anOptionalInt != nil {
    print("Contains a value!")
} else {
    print("Doesn’t contain a value.")
}

ただし、オプションを使用する場合の99.9%の確率で、オプションが含まれている場合は、実際に含まれている値にアクセスする必要があります。これを行うには、オプションのバインディングを使用できます。

オプションのバインディング

オプションのバインディングを使用すると、オプションに値が含まれているかどうかを確認でき、ラップされていない値を新しい変数または定数に割り当てることができます。バインド後に新しい変数の値を変更する必要があるかどうif let x = anOptional {...}if var x = anOptional {...}に応じて、構文またはを使用します。

例えば:

if let number = anOptionalInt {
    print("Contains a value! It is \(number)!")
} else {
    print("Doesn’t contain a number")
}

これは、最初にオプションに値が含まれていることを確認します。それは場合に行い、その後、「開封された」の値は、新しい変数(に割り当てられているnumber、それは非オプションであるかのようにあなたが自由に使用することができます- )。オプションに値が含まれていない場合は、予想どおり、else句が呼び出されます。

オプションのバインディングの優れている点は、複数のオプションを同時にアンラップできることです。ステートメントはコンマで区切ることができます。すべてのオプションがアンラップされている場合、ステートメントは成功します。

var anOptionalInt : Int?
var anOptionalString : String?

if let number = anOptionalInt, let text = anOptionalString {
    print("anOptionalInt contains a value: \(number). And so does anOptionalString, it’s: \(text)")
} else {
    print("One or more of the optionals don’t contain a value")
}

もう1つの巧妙なトリックは、値をアンラップした後、コンマを使用して値の特定の条件を確認できることです。

if let number = anOptionalInt, number > 0 {
    print("anOptionalInt contains a value: \(number), and it’s greater than zero!")
}

ifステートメント内でオプションのバインディングを使用する場合の唯一の欠点は、ステートメントのスコープ内からのみアンラップされた値にアクセスできることです。ステートメントの範囲外から値にアクセスする必要がある場合は、ガードステートメントを使用できます。

ガード文はあなたが成功するための条件を定義することができます-そしてその条件が満たされた場合、現在のスコープにのみ実行を継続します。それらは構文で定義されますguard condition else {...}

したがって、オプションのバインディングでそれらを使用するには、次のようにします。

guard let number = anOptionalInt else {
    return
}

(ガード本体内で、現在実行中のコードのスコープを終了するには、制御転送ステートメントの1つを使用する必要があることに注意してください)。

場合はanOptionalInt値が含まれ、それが開封され、新しいに割り当てられますnumber定数。その後、ガードののコードは実行を継続します。値が含まれていない場合、ガードは角かっこで囲まれたコードを実行します。これにより、制御が転送されるため、直後のコードは実行されません。

ガードステートメントの本当に素晴らしい点は、ラップされていない値がステートメントに続くコードで使用できるようになったことです(将来のコードはオプションに値がある場合にのみ実行できることがわかっているため)。これは、複数のifステートメントをネストすることによって作成された「運命のピラミッド」を排除するのに最適です。

例えば:

guard let number = anOptionalInt else {
    return
}

print("anOptionalInt contains a value, and it’s: \(number)!")

ガードは、複数のオプションを同時にアンラップしたり、where句を使用したりするなど、ifステートメントがサポートしたのと同じ巧妙なトリックもサポートします。

ifステートメントとguardステートメントのどちらを使用するかは、将来のコードでオプションに値を含める必要があるかどうかによって異なります。

ヌル合体演算子

無記号合体演算子の気の利いた簡略版である三条件演算子主として非optionalsとoptionalsを変換するために設計されました、。構文a ?? bはです。ここaで、はオプションの型でbあり、と同じ型ですa(ただし、通常はオプションではありません)。

基本的aに、「値が含まれている場合は、それをアンラップします。戻らない場合は、b代わりに」。たとえば、次のように使用できます。

let number = anOptionalInt ?? 0

これnumberにより、Int型の定数が定義されます。この定数には、値が含まれている場合はanOptionalInt、の値が含まれるか、そうでない場合が含まれ0ます。

これは、次の略記です。

let number = anOptionalInt != nil ? anOptionalInt! : 0

オプションのチェーン

オプションのチェーンを使用して、メソッドを呼び出したり、オプションのプロパティにアクセスしたりできます。これは、変数名を?使用するときに変数名の末尾にaを付けるだけで実行できます。

たとえばfoo、オプションのFooインスタンス型の変数があるとします。

var foo : Foo?

foo何も返さないメソッドを呼び出したい場合は、次のようにするだけです。

foo?.doSomethingInteresting()

場合はfoo値が含まれ、この方法は、それに呼び出されます。そうでない場合、悪いことは何も起こりません–コードは単に実行を続けます。

(これはnil、Objective-Cでメッセージを送信するのと同様の動作です)

したがって、これを使用してプロパティを設定したり、メソッドを呼び出したりすることもできます。例えば:

foo?.bar = Bar()

繰り返しますが、fooがあれば、ここで悪いことは何も起こりませんnil。コードは単に実行を継続します。

オプションのチェーンでできるもう1つの巧妙なトリックは、プロパティの設定またはメソッドの呼び出しが成功したかどうかを確認することです。これを行うには、戻り値をと比較しnilます。

(これは、何も返さないメソッドではVoid?なく、オプションの値が返されるためですVoid

例えば:

if (foo?.bar = Bar()) != nil {
    print("bar was set successfully")
} else {
    print("bar wasn’t set successfully")
}

ただし、プロパティにアクセスしたり、値を返すメソッドを呼び出そうとしたりすると、少し注意が必要になります。fooオプションであるため、そこから返されるものもすべてオプションになります。これに対処するには、上記のメソッドのいずれかを使用して返されるオプションをアンラップするか、メソッドfooにアクセスしたり、値を返すメソッドを呼び出す前に、それ自体をアンラップします。

また、名前が示すように、これらのステートメントを「チェーン」することができます。これは、プロパティを持つfooオプションのプロパティがある場合、次のように記述できることを意味します。bazqux

let optionalQux = foo?.baz?.qux

繰り返しますが、foobazはオプションであるため、から返される値は、それ自体がオプションquxであるかどうかに関係なく、常にquxオプションになります。

map そして flatMap

オプションでよく使用さmapれないflatMap機能は、and関数を使用する機能です。これらを使用すると、オプション以外の変換をオプションの変数に適用できます。オプションに値がある場合は、特定の変換を適用できます。値がない場合は、残りnilます。

たとえば、オプションの文字列があるとします。

let anOptionalString:String?

map関数をそれに適用することにより、関数を使用stringByAppendingStringして別の文字列に連結することができます。

stringByAppendingStringオプションではない文字列引数を取るため、オプションの文字列を直接入力することはできません。ただし、を使用mapすることにより、値があるstringByAppendingString場合に使用できるようにすることができanOptionalStringます。

例えば:

var anOptionalString:String? = "bar"

anOptionalString = anOptionalString.map {unwrappedString in
    return "foo".stringByAppendingString(unwrappedString)
}

print(anOptionalString) // Optional("foobar")

ただし、anOptionalString値がない場合は、mapを返しnilます。例えば:

var anOptionalString:String?

anOptionalString = anOptionalString.map {unwrappedString in
    return "foo".stringByAppendingString(unwrappedString)
}

print(anOptionalString) // nil

flatMapクロージャー本体内から別のオプションmapを返すことができることを除いて、と同様に機能します。つまり、オプション以外の入力を必要とするプロセスにオプションを入力できますが、オプション自体を出力することはできます。

try!

Swiftのエラー処理システムはDo-Try-Catchで安全に使用できます:

do {
    let result = try someThrowingFunc() 
} catch {
    print(error)
}

someThrowingFunc()エラーをスローした場合、エラーはcatchブロック内で安全にキャッチされます。

errorあなたが見一定のcatchブロックは、当社が宣言されていない-それは自動的にによって生成されますcatch

error自分自身を宣言することもできます。これには、次のような便利な形式にキャストできるという利点があります。

do {
    let result = try someThrowingFunc()    
} catch let error as NSError {
    print(error.debugDescription)
}

tryこの方法を使用することは、関数のスローに起因するエラーを試行、キャッチ、および処理するための適切な方法です。

try?エラーを吸収するものもあります:

if let result = try? someThrowingFunc() {
    // cool
} else {
    // handle the failure, but there's no error information available
}

しかし、Swiftのエラー処理システムは、次の方法で「強制的に試す」方法も提供しますtry!

let result = try! someThrowingFunc()

この投稿で説明されている概念はここにも当てはまります。エラーがスローされると、アプリケーションがクラッシュします。

try!その結果がコンテキストで失敗しないことを証明できる場合にのみ使用する必要があります。これは非常にまれです。

ほとんどの場合、完全なDo-Try-Catchシステムを使用しますtry?。エラーの処理が重要でないまれなケースでは、オプションのシステムを使用します。


リソース

65
Sajjon 2016-12-20 03:26.

TL; DR回答

非常に少数の例外、このルールは黄金です。

の使用を避ける !

?暗黙的にアンラップされたオプション(IUO)ではなく、変数オプション()を宣言します(!

言い換えれば、むしろ使用してください:
var nameOfDaughter: String?

の代わりに:
var nameOfDaughter: String!

if letまたはを使用してオプションの変数をアンラップしますguard let

次のように変数をアンラップします。

if let nameOfDaughter = nameOfDaughter {
    print("My daughters name is: \(nameOfDaughter)")
}

またはこのように:

guard let nameOfDaughter = nameOfDaughter else { return }
print("My daughters name is: \(nameOfDaughter)")

この回答は簡潔にすることを目的としており、完全に理解するために受け入れられた回答を読んでください


リソース

40
Duncan C 2016-02-29 04:37.

この質問は、最大来るALL THE TIME SO上。これは、新しいSwift開発者が最初に苦労することの1つです。

バックグラウンド:

Swiftは、「オプション」の概念を使用して、値を含む場合と含まない場合がある値を処理します。Cのような他の言語では、変数に値0を格納して、値が含まれていないことを示す場合があります。ただし、0が有効な値である場合はどうなりますか?次に、-1を使用できます。-1が有効な値である場合はどうなりますか?等々。

Swiftオプションを使用すると、有効な値を含めるか、値を含めないように、任意のタイプの変数を設定できます。

変数を意味するように宣言するとき(タイプx、または値なし)、タイプの後に疑問符を付けます。

オプションは、実際には、特定のタイプの変数を含むか、何も含まないコンテナです。

内部の値をフェッチするには、オプションを「ラップ解除」する必要があります。

「!」演算子は「強制アンラップ」演算子です。「私を信じてください。私が何をしているのか知っています。このコードが実行されるとき、変数にnilが含まれないことを保証します。」と書かれています。あなたが間違っているなら、あなたは墜落します。

自分が何をしているのか本当にわからない限り、「!」は避けてください。アンラップ演算子を強制します。これはおそらく、Swiftプログラマーを始めたばかりの人にとって最大のクラッシュの原因です。

オプションの扱い方:

より安全なオプションを処理する方法は他にもたくさんあります。ここにいくつかあります(完全なリストではありません)

「オプションのバインディング」または「iflet」を使用して、「このオプションに値が含まれている場合は、その値を新しい非オプションの変数に保存します。オプションに値が含まれていない場合は、このifステートメントの本文をスキップします。 "。

オプションのバインディングの例を次に示しfooます。

if let newFoo = foo //If let is called optional binding. {
  print("foo is not nil")
} else {
  print("foo is nil")
}

オプションの入札を使用するときに定義する変数は、ifステートメントの本体にのみ存在する(「スコープ内」にのみ存在する)ことに注意してください。

または、guardステートメントを使用して、変数がnilの場合に関数を終了することもできます。

func aFunc(foo: Int?) {
  guard let newFoo = input else { return }
  //For the rest of the function newFoo is a non-optional var
}

GuardステートメントはSwift2で追加されました。Guardを使用すると、コード全体で「ゴールデンパス」を保持し、「iflet」オプションのバインディングを使用することで発生することがあるネストされたifのレベルが増え続けるのを防ぐことができます。

「nil合体演算子」と呼ばれる構造もあります。「optional_var ?? replacement_val」の形式を取ります。オプションに含まれるデータと同じタイプの非オプション変数を返します。オプションにnilが含まれている場合、「??」の後に式の値を返します。シンボル。

したがって、次のようなコードを使用できます。

let newFoo = foo ?? "nil" // "??" is the nil coalescing operator
print("foo = \(newFoo)")

try / catchまたはguardエラー処理を使用することもできますが、通常、上記の他の手法の1つはよりクリーンです。

編集:

オプションを使用したもう1つの微妙な落とし穴は、「暗黙的にラップされていないオプションです。fooを宣言すると、次のようになります。

var foo: String!

その場合、fooはオプションですが、参照するためにラップを解除する必要はありません。つまり、fooを参照しようとすると、それがnilの場合はクラッシュします。

したがって、このコード:

var foo: String!


let upperFoo = foo.capitalizedString

fooを強制的にアンラップしていなくても、fooのcapitalizedStringプロパティを参照するとクラッシュします。印刷はきれいに見えますが、そうではありません。

したがって、暗黙的にアンラップされたオプションには本当に注意する必要があります。(そして、オプションをしっかりと理解するまでは、それらを完全に回避することもできます。)

結論:Swiftを初めて学習するときは、「!」のふりをしてください。文字は言語の一部ではありません。トラブルに巻き込まれる可能性があります。

13
Tharzeez 2017-11-18 06:15.

上記の回答は、オプションで安全にプレイする方法を明確に説明しているためです。オプションが本当に迅速に何であるかを説明しようとします。

オプションの変数を宣言する別の方法は

var i : Optional<Int>

そして、オプションタイプは2つのケースの列挙に他なりません。

 enum Optional<Wrapped> : ExpressibleByNilLiteral {
    case none 
    case some(Wrapped)
    .
    .
    .
}

したがって、変数 'i'にnilを割り当てます。できる var i = Optional<Int>.none か、値を割り当てるために、いくつかの値を渡します var i = Optional<Int>.some(28)

swiftによると、「nil」は価値の欠如です。そして、で初期化されたインスタンスを作成するnilと呼ばれるプロトコルに準拠しなければならない私たちにExpressibleByNilLiteral、あなたはそれを推測した場合、大きなだけOptionalsに準拠ExpressibleByNilLiteralして、他のタイプに適合することはお勧めできません。

ExpressibleByNilLiteralinit(nilLiteral:)instaceをnilで初期化するという単一のメソッドがあります。通常、このメソッドを呼び出すことはありません。迅速なドキュメントによると、オプションの型をnilリテラルで初期化するたびにコンパイラが呼び出すため、このイニシャライザを直接呼び出すことはお勧めしません。

私でさえ(しゃれを意図せずに)頭を包む必要があります。オプション:D Happy SwftingAll

12
QiunCheng 2016-07-30 21:18.

まず、オプションの値が何であるかを知っておく必要があります。あなたはにステップすることができスウィフトプログラミング言語の詳細について。

次に、オプションの値には2つのステータスがあることを知っておく必要があります。1つは完全な値で、もう1つはゼロ値です。したがって、オプションの値を実装する前に、それがどの状態であるかを確認する必要があります。

あなたは使用することができるif let ...guard let ... elseのように。

もう1つの方法は、実装前に変数の状態を確認したくない場合は、var buildingName = buildingName ?? "buildingName"代わりに使用することもできます。

8
Wissa 2018-04-14 04:06.

次のように、prepare for segueメソッドからOutlets値を設定しようとしたときに、このエラーが発生しました。

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let destination = segue.destination as? DestinationVC{

        if let item = sender as? DataItem{
            // This line pops up the error
            destination.nameLabel.text = item.name
        }
    }
}

次に、コントローラーがまだロードまたは初期化されていないため、宛先コントローラーのアウトレットの値を設定できないことがわかりました。

だから私はそれをこのように解決しました:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let destination = segue.destination as? DestinationVC{

        if let item = sender as? DataItem{
            // Created this method in the destination Controller to update its outlets after it's being initialized and loaded
            destination.updateView(itemData:  item)
        }
    }
}

宛先コントローラー:

// This variable to hold the data received to update the Label text after the VIEW DID LOAD
var name = ""

// Outlets
@IBOutlet weak var nameLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
    nameLabel.text = name
}

func updateView(itemDate: ObjectModel) {
    name = itemDate.name
}

この回答が、マークされた回答がオプションとその機能を理解するための優れたリソースであることがわかったのと同じ問題を抱えている人に役立つことを願っていますが、問題自体には直接対処していません。

7
Cristik 2018-09-19 20:04.

基本的に、Swiftがnil以外の値のみを許可する場所でnil値を使用しようとしました。これは、コンパイラにnil値が存在しないことを信頼するように指示して、アプリをコンパイルできるようにすることです。

この種の致命的なエラーにつながるシナリオはいくつかあります。

  1. 強制アンラップ:

    let user = someVariable!
    

    someVariableがnilの場合、クラッシュします。強制アンラップを実行することで、nilチェックの責任をコンパイラーから自分に移しました。基本的に強制アンラップを実行することで、コンパイラーにnil値がないことを保証します。そして、どういうわけかnil値がで終わる場合に何が起こるかを推測しsomeVariableますか?

    解決?オプションのバインディング(別名if-let)を使用し、そこで変数処理を実行します。

    if user = someVariable {
        // do your stuff
    }
    
  2. 強制(ダウン)キャスト:

    let myRectangle = someShape as! Rectangle
    

    ここでは、強制的にキャストすることで、常にRectangleインスタンスが存在するため、コンパイラに心配しないように指示します。そしてそれが成り立つ限り、あなたは心配する必要はありません。問題は、プロジェクトのあなたまたはあなたの同僚が長方形以外の値を循環し始めたときに始まります。

    解決?オプションのバインディング(別名if-let)を使用し、そこで変数処理を実行します。

    if let myRectangle = someShape as? Rectangle {
        // yay, I have a rectangle
    }
    
  3. 暗黙的にアンラップされたオプション。次のクラス定義があると仮定しましょう。

    class User {
        var name: String!
    
        init() {
            name = "(unnamed)"
        }
    
        func nicerName() {
            return "Mr/Ms " + name
        }
    }
    

    これで、nameプロパティをに設定して誰もプロパティを台無しにしない場合nil、期待どおりに機能しUserますが、nameキーがないJSONから初期化された場合、プロパティを使用しようとすると致命的なエラーが発生します。

    解決?それらを使用しないでください:)プロパティが使用される必要があるときまでに常にnil以外の値を持つことが102%確実でない限り。ほとんどの場合、オプションまたは非オプションへの変換が機能します。これをオプション以外にすると、コンパイラは、見逃したコードパスにそのプロパティに値を指定することで、それを支援します。

  4. 接続されていない、またはまだ接続されていないコンセント。これはシナリオ#3の特定のケースです。基本的に、使用したいXIBロードクラスがいくつかあります。

    class SignInViewController: UIViewController {
    
        @IBOutlet var emailTextField: UITextField!
    }
    

    XIBエディターからコンセントへの接続を逃した場合、コンセントを使用するとすぐにアプリがクラッシュします。解決?すべてのコンセントが接続されていることを確認してください。または?、それらに演算子を使用しますemailTextField?.text = "[email protected]"。または、アウトレットをオプションとして宣言します。ただし、この場合、コンパイラーはコード全体でアウトレットをアンラップするように強制します。

  5. Objective-Cからの値であり、null可能性アノテーションがありません。次のObjective-Cクラスがあると仮定しましょう。

    @interface MyUser: NSObject
    @property NSString *name;
    @end
    

    これで、null可能性アノテーションが(明示的にまたはNS_ASSUME_NONNULL_BEGIN/を介してNS_ASSUME_NONNULL_END)指定されていない場合、nameプロパティはSwiftにString!(IUO-暗黙的にラップ解除されたオプション)としてインポートされます。一部の迅速なコードが値を使用するようになるとすぐに、nameがnilの場合はクラッシュします。

    解決?ヌル可能性アノテーションをObjective-Cコードに追加します。ただし、Objective-Cコンパイラは、null可能性に関しては少し寛容であり、明示的にnonnull。としてマークした場合でも、nil値になる可能性があることに注意してください。

2
Honey 2018-11-01 18:39.

これはもっと重要なコメントであり、nil値のデバッグに関しては、暗黙的にアンラップされたオプションが誤解を招く可能性がある理由です。

次のコードについて考えてみてください。エラー/警告なしでコンパイルされます。

c1.address.city = c3.address.city

ただし、実行時に次のエラーが発生します。致命的なエラー:オプション値のラップ解除中に予期せずnilが見つかりました

どのオブジェクトnilか教えていただけますか?

できません!

完全なコードは次のようになります。

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        var c1 = NormalContact()
        let c3 = BadContact()

        c1.address.city = c3.address.city // compiler hides the truth from you and then you sudden get a crash
    }
}

struct NormalContact {
    var address : Address = Address(city: "defaultCity")
}

struct BadContact {
    var address : Address!
}

struct Address {
    var city : String
}

簡単に言うと、変数が他の読者からのものである可能性を隠しているというvar address : Address!ことです。そして、それがクラッシュしたとき、あなたは「一体何なの?!私はオプションではないのに、なぜ私はクラッシュするのですか?!」のようです。niladdress

したがって、次のように書くことをお勧めします。

c1.address.city = c2.address!.city  // ERROR:  Fatal error: Unexpectedly found nil while unwrapping an Optional value 

それがどのオブジェクトだったのnilか教えていただけますか?

今回は、コードがより明確になりました。あなたは合理化して、addressそれが強制的にアンラップされたパラメータである可能性が高いと考えることができます。

完全なコードは次のようになります。

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        var c1 = NormalContact()
        let c2 = GoodContact()

        c1.address.city = c2.address!.city
        c1.address.city = c2.address?.city // not compile-able. No deceiving by the compiler
        c1.address.city = c2.address.city // not compile-able. No deceiving by the compiler
        if let city = c2.address?.city {  // safest approach. But that's not what I'm talking about here. 
            c1.address.city = city
        }

    }
}

struct NormalContact {
    var address : Address = Address(city: "defaultCity")
}

struct GoodContact {
    var address : Address?
}

struct Address {
    var city : String
}
2
Ale Mohamad 2019-05-21 07:34.

エラーはEXC_BAD_INSTRUCTIONfatal error: unexpectedly found nil while implicitly unwrapping an Optional valueを宣言した@IBOutletストーリーボードに接続していない場合に最も多く表示されます。

他の回答で言及されているように、オプションがどのように機能するかについても学ぶ必要がありますが、これは私に主に表示される唯一の時間です。

2
ShigaSuresh 2020-02-13 08:16.

CollectionViewでこのエラーが発生した場合は、CustomCellファイルとカスタムxibも作成してみてください。

mainVCのViewDidLoad()にこのコードを追加します。

    let nib = UINib(nibName: "CustomnibName", bundle: nil)
    self.collectionView.register(nib, forCellWithReuseIdentifier: "cell")
0
Mike Volmar 2019-09-27 05:11.

メインストーリーボードでビューコントローラーのカスタムクラス名を指定するのを忘れたため、テーブルビューコントローラーからビューコントローラーにセグエを作成しているときにこのエラーが発生しました。

他のすべてが問題ないように見えるかどうかを確認する価値のある単純なもの

Related questions

MORE COOL STUFF

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは、夫に会ったとき、典型的な交際のアドバイスに逆らいました。

マイケルシーンが非営利の俳優である理由

マイケルシーンが非営利の俳優である理由

マイケルシーンは非営利の俳優ですが、それは正確にはどういう意味ですか?

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

特徴的なスターのコリン・エッグレスフィールドは、RomaDrama Liveでのスリル満点のファンとの出会いについて料理しました!加えて、大会での彼のINSPIREプログラム。

「たどりつけば」をオンラインでストリーミングできない理由

「たどりつけば」をオンラインでストリーミングできない理由

ノーザンエクスポージャーが90年代の最も人気のある番組の1つになった理由を確認するには、Blu-rayまたはDVDプレーヤーをほこりで払う必要があります。

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖は、世界で2番目に大きいボイリング湖です。そこにたどり着くまでのトレッキングは大変で長いですが、努力する価値は十分にあります。

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

サロンからのヘアトリミングや個人的な寄付は、油流出を吸収して環境を保護するのに役立つマットとして再利用できます。

ホワイトハウスの最も記憶に残る結婚式を見てください

ホワイトハウスの最も記憶に残る結婚式を見てください

過去200年以上の間にホワイトハウスで結婚したのはほんの数人です。彼らは誰でしたか、そしてそこで結婚式を獲得するために何が必要ですか?

今週のコミックコンですべての素晴らしいものに追いつく方法

今週のコミックコンですべての素晴らしいものに追いつく方法

サンディエゴコミックコンは今週開幕し、オタクのアナウンス、ポスター、予告編、お気に入りの番組や映画のからかいでいっぱいになります。SDCCは、コンベンションフロア全体の多くのパネルで行われているため、すべてに対応するのは難しい場合があります。

Googleの9千万ドルの和解はアプリ開発者にとってもGoogleにとっても勝利ですか?

Googleの9千万ドルの和解はアプリ開発者にとってもGoogleにとっても勝利ですか?

小さなアプリ開発者は金曜日に発表された法的な和解でグーグルから9千万ドルをこじ開けた。アップルとの同様の合意に続いて熱くなった。金曜日のブログ投稿で、Googleは、Androidメーカーが市場での優位性を悪用してPlayストア経由でのアプリ内購入に対して30%の料金を不当に請求したと主張するアプリ開発者との訴訟を解決するために、9千万ドルを支払うことに合意したと述べました。

RadioShackのTwitterはハッキングされていませんでした、それはただの暗号のサクラです

RadioShackのTwitterはハッキングされていませんでした、それはただの暗号のサクラです

今週、RadioShackのTwitterアカウントは、奇妙なものから完全にひどいものになりました。短い順序で、会社のフィード全体が、バイブレーター、「ビッグティット」(スペルミス)、有名人やその他の企業アカウントを荒らしているツイートなど、NSFW素材の真の山になりました。

ヒッグス粒子から10年後、物理学にとって次の大きなものは何ですか?

ヒッグス粒子から10年後、物理学にとって次の大きなものは何ですか?

大型ハドロン衝突型加速器のトンネル内にあるコンパクトミュオンソレノイド(CMS)検出器。2012年7月4日、CERNの科学者たちは、1960年代に最初に提案された素粒子であるヒッグス粒子の観測を確認しました。

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya shared a sweet photo in honor of boyfriend Tom Holland's 26th birthday Wednesday

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

シーレン「Ms.JuicyBaby」ピアソンは、先月脳卒中で入院した後、「もう一度たくさんのことをする方法を学ばなければならない」ため、言語療法を受けていることを明らかにしました。

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

オスカー受賞者の世紀半ばの家には、3つのベッドルーム、2つのバス、オーシャンフロントの景色があります。

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、生後4か月の娘、モナコに母乳育児をしていると語った。

Un breve viaje espacial sobre conceptualizar el diseño

Complicarse la vida, mezclar churros con meninas (nada de ovejas) y encontrar valor en un trastero que adquiriste en una puja.

Un breve viaje espacial sobre conceptualizar el diseño

Bien. Hay un momento en toda salida al espacio exterior en el que de la tensión, la velocidad y las altas temperaturas derivadas del cruce de estratosfera a ionosfera se pasa a un momento de súbita calma, donde se despliega la vista completa del paisaje espacial que nos rodea.

Seguindo Todos os Protocolos (2022), de Fábio Leal

Seguindo Todos os Protocolos (2022), de Fábio Leal

Chico quer transar. Até aí, tudo bem.

多元宇宙—Junø

多元宇宙—Junø

チェーン間アカウントがJunoに登場します。異なるブロックチェーン間でスマートコントラクトの構成可能性と真の相互運用性を提供します。

#brand【ベター・コール・ソール!アメリカのテレビシリーズ「ブレイキング・バッド」に最高のビジネス例が隠されている】・・・ルールクリエイティブ

#brand【ベター・コール・ソール!アメリカのテレビシリーズ「ブレイキング・バッド」に最高のビジネス例が隠されている】・・・ルールクリエイティブ

1.ドラマを見た後、起業する考えはありますか?あなたのビジネスはボトルネックに遭遇しましたか?方向性がなくてわからない場合は、ドラマを追いかけて行くことを心からお勧めします。(?)ブラフではなく、最も完璧なビジネス例を隠すドラマがあります。2.ブレイキング・バッドとその弁護士ドラマ「ブレイキング・バッド」を見た友人たちは、演劇の中で、穏やかな表情で、弁護士のソウル・グッドマンに深く感銘を受けなければなりません。口を開けて、感覚の弱い傭兵の性格を持っています。道徳の面で、サル・グッドマンは無意識のうちに劇に欠かせない役割を果たし、彼自身のシリーズ「絶望的な弁護士」(ベター・コール・ソール)を生み出しました。ウェントウのテキストとビデオは、劇中のソウル・グッドマンのテレビコマーシャルです。製品(サービス)、競争戦略、市場ポジショニング、ブランド名、ターゲット顧客グループ、コミュニケーション軸から広告まで、サル・グッドマンの役割のビジネス設定は、「最低」と見なすことができる超超超超超超完全です。ブランドコミュニケーションのコスト」「変化」のモデル。なぜ?私の分析をご覧ください。3.ソウル・グッドマンの「事業戦略」1.基本情報ブランド名:Saul Goodman製品:法律相談サービス対象顧客:麻薬中毒、飲酒運転、事故など。法律知識の欠如は、一般的に公立弁護士にしか余裕がなく、真面目な弁護士も「特別な法律を持つ消費者」を避けます。恐れてはいけない「​​ニーズ」。コミュニケーションの主軸:この国のすべての男性、女性、子供は有罪判決を受けるまで無実だと思います。地域:アルバカーキ市スローガン:Thrallに電話したほうがいいです!(ベター・コール・ソール)広告:2つの可能性のある犯罪状況をシミュレートします+サウルの主張+サウルのスローガン2をより適切に呼び出します。

Language