29
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SwiftでUIImageのimageNamed:でファイルが存在しなかったときに起こる謎

Last updated at Posted at 2014-07-28

このバグはSwift ver1 がBetaだったときのバグです。現在は発生しません。

Objective-Cで何気なく使っているUIImageimageNamed:メソッド。自分の頭では理解できないことがあったので教えてほしいです。

imageNamed:メソッド、プロジェクトに入っている画像名を指定してこんな感じ使ってると思います。

UIImage *image = [UIImage imageNamed:@"my_image"];

Swiftだとこんな感じ。

let image:UIImage = UIImage(named:"my_image")

御存じだと思いますが、このimageNamed:ファイルが見つからないとnilを返しますね。

Objective-Cだと、ファイルが見つからなかった場合は**何も表示されません。**ダウンロードしてきた画像は生成できるかnilチェックすると思うのですが、ローカルの画像はついついnilチェックを怠ってしまい、画像が表示されていないことに気づかない可能性も出てきます。アプリの規模が大きくなると画像も増えますし困りもんです。

ではSwiftではどうなるか?

まず前提知識として、Swiftはnilを許容しません。基本的にnilを扱うことができないんです。

かといって全く扱えないのは困るのでnilを使いたい場合はOptional型というものにする必要があるのです(OptionalについてはSwiftのOptionalとType Safetyなどを参照してください)。

こんな感じ。ファイルが存在しなくても安全に処理できます。

var imageView: UIImageView

// ?をつけることでOptional型に
let image:UIImage? = UIImage(named:"my_image")

// Optional Bindingでnilチェック
if let validImage = image {
    imageView = UIImageView(image: validImage)
} else {
    // 画像がなかった場合の処理
}

上記のコードは問題ありません。

次を見てみましょう。

let image:UIImage = UIImage(named:"my_image")
var imageView: UIImageView = UIImageView(image:image)

これで"my_image"ファイルが存在していなかった場合どうなるか?nilが返ってきますね。

なぜこんなことを書いているかというとObjective-Cのコードを何も考えずにSwiftに書き直したらこのコードになったからです。

UIImage *image = [UIImage imageNamed:@"my_image"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];

このObjective-Cを、こうSwiftしてしまった。

let image:UIImage = UIImage(named:"my_image")
var imageView: UIImageView = UIImageView(image: image)

で、書き終わった段階で存在しない"my_image"からインスタンス化しようとする、つまりnilが返ってきて落ちるだろうということに気がついてXcode6(Beta4)で実行してみたところ。。。

**何もエラーが出ない。**しかもimageインスタンスはnil。Optionalじゃないのに。

println("\(image === nil)") // true

もちろん、これが原因でアプリが落ちるよりも画像が表示されないだけで済む方が良いです。そしてOptionalの存在しないObjective-Cと矛盾は起きない。Optionalを意識せずに書き換えても問題なく動く。

でも、文法的にはimageNamed:の返り値はOptionalであるべきで、UIImage変数もOptionalにするべきなのではないのだろうかと思ったワケです。

分からない。分かる人がいれば教えてほしい!

##追記(201407/29)
imageViewのimageプロパティはImplicitly Unwrapped Optionalsなので、nilが代入

29
30
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?