HOME > unexpectedly found nil while unwrapping an Optional value
unexpectedly found nil while unwrapping an Optional valueの対応
よく発生するがいまいちわかっていないOptional型のエラーの解説です。
この英語、直訳すれば Optional型の値をアンラップした時に予期せぬnilを見つけましたとなります。Unwrapする方法は覚えておられるでしょうか?びっくりマークをつけることでアンラップします。
Optional型の以前の記事はこちらから ー>クエスチョンマークとビックリマーク
やってみた
まずこのエラーを再現させてみます。
//テスト用のクラスを作成
class SwiftSalaryMan {
func sayRequestToCompany() -> String {
return "週休五日制希望"
}
}
//Optional型でSwiftSalaryManを宣言
var wrappedSwiftSalaryMan: SwiftSalaryMan? = SwiftSalaryMan()
//nilを入れてForcedUnwrapして実行
wrappedSwiftSalaryMan = nil;
println(wrappedSwiftSalaryMan!.sayRequestToCompany());
->結果(ランタイムエラー:fatal error: unexpectedly found nil while unwrapping an Optional valueが表示)
Optional型で宣言したクラスにnilを入れて実行させた場合に発生しました。
Swift言語的には実施して欲しくなクラッシュする手順。 ただ、なんとなくしっくりきません。Optional型にしたりラップしたり、アンラップしたり、、、意味がこんがらがります。。。Unwrapする方法によってエラーが違ってくるので混乱している気がしますので、nilを入れなかった場合や、!をつけない、?をつけてみるの方法で結果を表示してみます
Optional型のwrappedSwiftSalaryMan?に「nilを入れない」でテスト
var wrappedSwiftSalaryMan: SwiftSalaryMan? = SwiftSalaryMan()
//wrappedSwiftSalaryMan = nil;
//①何もつけない
println(wrappedSwiftSalaryMan.sayRequestToCompany());
->結果(コンパイル失敗:エラーでCompiler error: 'SwiftSalaryMan?' does not have a member named 'sayRequestToCompany')
//②びっくりマークをつける
println(wrappedSwiftSalaryMan!.sayRequestToCompany());
->結果(実行成功:String型で週休五日制希望をログ出力)
//③クエスチョンマークをつける
println(wrappedSwiftSalaryMan?.sayRequestToCompany());
->結果(実行成功:OptionalのString型で週休五日制希望をログ出力)
Optional型のwrappedSwiftSalaryMan?に「nilを入れて」テスト
var wrappedSwiftSalaryMan: SwiftSalaryMan? = SwiftSalaryMan()
wrappedSwiftSalaryMan = nil;
//①何もつけない
println(wrappedSwiftSalaryMan.sayRequestToCompany());
->結果(コンパイル失敗:エラーでCompiler error: 'SwiftSalaryMan?' does not have a member named 'sayRequestToCompany')
//②びっくりマークをつける
println(wrappedSwiftSalaryMan!.sayRequestToCompany());
->結果(ランタイムエラー:この記事のエラー<unexpectedly found nil while unwrapping an Optional value>)
//③クエスチョンマークをつける
println(wrappedSwiftSalaryMan?.sayRequestToCompany());
->結果(実行成功:nilをログ出力)
デフォルトのwrappedSwiftSalaryManに「nilを入れない」でテスト(Optional型にしない)
var wrappedSwiftSalaryMan: SwiftSalaryMan = SwiftSalaryMan()
//①何もつけない
println(wrappedSwiftSalaryMan.sayRequestToCompany());
->結果(実行成功:String型で週休五日制希望をログ出力)
//②びっくりマークをつける
println(wrappedSwiftSalaryMan!.sayRequestToCompany());
->結果(コンパイルエラー:Operant of postfix '!' should have optional type)
//③クエスチョンマークをつける
println(wrappedSwiftSalaryMan?.sayRequestToCompany());
->結果(コンパイルエラー:Operant of postfix '?' should have optional type)
デフォルトのwrappedSwiftSalaryManに「nilをいれて」テスト(Optional型にしない)
var wrappedSwiftSalaryMan: SwiftSalaryMan = SwiftSalaryMan()
wrappedSwiftSalaryMan = nil;
->結果(コンパイルエラー:does not conform to protocol 'NilLiteralConvertible')
まとめ
いろいろ書いてOptional型の説明のようになってしまいました、、、、説明のつもりが逆にややこしくなっているかもしれません。
つまりクエスチョンマークをつけた場合はOptional型のままでアクセス、 びっくりマークの場合はアンラップした状態でアクセス、と「Optional型のクラスはメンバ変数や関数へのアクセスする選択肢が2つ存在する」が混乱する理由なのではと思いました。
すこしでも何か理解のきっかけになれば幸いです
↓こんな記事もありますよ!
![]() | アプリを常にActiveにForegroundにした状態で写真を撮影できるか写真は音をたてないと撮影できなかったり不便なことが多いのでできるのかよくわかりませんので検証 |
![]() | デバッグ時とリリース時に処理を変更する#ifdef DEBUG のやり方DEBUG時だけ特定の動作をさせて、リリース時に排除したい、そんな時に利用する方法です。Swiftでは標準ではDEBUGとリリースの判断がつかないので、 コンパイル時に設定する必要があります |
![]() | UITextViewでテキストを複数行表示するUITextFieldは一行表示ですが、UITextFieldは複数行を表示することができます。 |
Tweet
![]() |
|||
|