最近、iOSアプリ開発に関する記事ばかりですが…今日も今日とて、アプリ開発中に遭遇したエラーについてです。
エラー文はこちら。
Unexpectedly found nil while unwrapping an Optional value
Google翻訳を使って翻訳したところ、「オプショナル値をアンラッピングしている間に予期せずnilが見つかりました」とのこと。
ある程度アプリ開発をしている人なら原因はすぐに分かるか、もしくはそもそもこのエラーが発生しないように対処済みかと思います。
が、Swift 初心者だと、オプショナル型が理解しづらく(実体験)、なかなかハマったのでまとめます。
今回参考にさせていただいたサイトはこちらから。
どこよりも分かりやすいSwiftの”?”と”!” – Qiita
https://qiita.com/maiki055/items/b24378a3707bd35a31a8
まずオプショナル型がイマイチわからない…という人は、この記事よりもこのリンクを読みましょう。
さて、対処方法ですが、まずエラーが発生したコードがこちら。
var title: Sting! // オプショナル型 /* 何らかの処理 */ print(title!);
簡単に説明すると、上記のコードの title という変数は、nil(null)を代入できるオプショナル型です。
非オプショナル型と違い、代入された値がラップ(包み紙)に包まれています。
これのおかげで、nil を扱うことができています。
で、この変数にタイトルのテキストを代入するなどの処理を行い、結果を print() で出力しています。
が、このとき、何らかの原因で、title変数に値が代入されないことがあります。
そして、中身が nil の状態で、包み紙を剥がすアンラップの処理を行うと、エラーが発生します。
このエラーが、今回紹介した「Unexpectedly found nil while unwrapping an Optional value」です。
これを解決するために、アンラップの処理を下記のように変更します。
// 変更前 // print(title!); // 変更後 if let unwrap_title = title { print(unwrap_title) } else { print("値が代入されていません") }
なお、この方法を「オプショナルバインディング」と言います。
簡単に解説すると、新しいコードでは、まずオプショナル型の変数を if 文以降の定数に代入しています。
その結果が nil でなかれば、if 以下の処理が実行されます。
一方で、title を代入した定数が nil であれば、else 以下の処理が実行されます。
なお、title の値は unwrap_title に代入されていますので、こちらを利用します。
処理としては以上です。
最初に紹介したアンラップ方法は、「強制的アンラップ」といい、文字通り代入された値に関係なくアンラップの処理を行います。
この方法は、絶対に nil が代入されない変数に対してのみ使うようにしてください。
そうでなければ、オプショナルバインディングを使うことを強く推奨します。
私も最初はオプショナル型が全く理解できず、かなり苦労しました。
個人的には、実際にコードを書いてみて、どういうときにプログラムが落ちるのかを体験するとわかりやすいかなと思います。