Swift転職なら=>【LevTech】
↑クリックして拡大
↑クリックして拡大
↑クリックして拡大
↑クリックして拡大

頭痛が減ったので共有です!

rebuild.fmを応援しています!

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つ存在する」が混乱する理由なのではと思いました。

すこしでも何か理解のきっかけになれば幸いです

↓こんな記事もありますよ!

Facebook SDK のAppEventを検証する

さて、AppEventですが、FacebookのAppを利用したログシステムなのかな。ログをカスタマイズして保存して、 それを解析できる、そんな感じなのかなと思っています。 広告利用の為に、インストールされた数やログの解析によってユーザの動作を確認できるようですので細かく設定できるのではと思います。 まずは上記のようにログを保存する、ログを読み込む、ができるのかを検証してみます

カスタムクラスを作成時いつも忘れる。継承クラス作成時のメモ

カスタムクラスを作成する時いつもUIViewを継承する際のrequired Initの箇所でハマってしまうので覚書です。

UISwitchで切り替えスイッチコントロール

スイッチによるONOFFを実装するためのコントロールの説明です。
このエントリーをはてなブックマークに追加
右側のFacebookのLikeをクリック頂けると記事更新の際に通知されますので宜しければご利用下さい!