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

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

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

CLLocationManagerで現在位置を取得

あっさりしたシンプルなサンプルがなかったので省略型です。

AppleWatchのアプリ登録が開始されました、開発部分を少し翻訳

ItunesconnectにもAppleWatchのアイコン やスクリーンショットが登録できる画面が追加されています。あと24日、登録予定している人は審査を考えても後10日程度ではないでしょうか。 スタートダッシュに追いつくには今が頑張りどころなのかもしれません!

willsetとdidsetでプロパティを監視。意味あるのか???

クラスのプロパティにはWillsetとdidsetという監視用の関数があると聞いたのですが、用途は分かるにしても メリットとしてはどういうものなのかなと、うーん、と考えていました。調べていると海外のサイトでは同じように疑問にもつ質問があがっていました。 getとsetで同じことができるのでは?との私と同じスタンスです。解決されていましたので、順に説明していきます。
このエントリーをはてなブックマークに追加
右側のFacebookのLikeをクリック頂けると記事更新の際に通知されますので宜しければご利用下さい!