うるおいらんど

アプリ開発やサイト制作のメモとか。

【Swift 3】UIImage(named:)の代わりにUIImage(contentsOfFile:)を使ったらメモリに優しくなれた

魚ライン
魚ライン



重いアプリをどうにかしようと絶賛奮闘中のReoです。

色々とメモリリークする原因は探り中なのですが、今回1つわかったことがあるのでメモメモしていきます。UIImageに関する件です。

 

今までずっと画像ファイルを読み出すときは、UIImageのイニシャライザはinit(named:)の方を用いていました。

メモリリーク関連を調べている時にこちらの質問にたどり着いてちょっと衝撃でした。

UIImage named: のメモリ解放について -teratail

こちらによると、init(named:)の方にはキャッシュ問題があるらしいです。

どうやら昔から言われている話らしい。全然知らなかった。

 

私のアプリでは、チュートリアルにUIImage(named: )の方を使って画像を読み込んで4ページくらいを表示させているんですが、それだけでも@2xとか@3xのを表示させると結構重たいんですね。

それが一度使われたら画面遷移した後でもそのまま解放されずにずーっと残っていました。

チュートリアルなんてそれこそ一回終わっちゃえばいらないのにいつまでたっても残ってて、本当にきつい。

 

それをinit(contentsOfFile:)の方を用いてみたら、ナントちゃんと解放された∩(〃・ω・〃)∩ ばんじゃーい!!!!

 

以下のような書き換えをしました。

 

これで解放されてくれるので素晴らしいのですが、さてさてここでまた問題が発生しました。

 

 

contentsOfFile:の方は@2xや@3xに自動対応しない

named:を用いた場合の1番の魅力は、用意しておけば自動的に@2xや@3xに対応してくれるってことだと思います。

image@2x.pngとimage@3x.pngをちゃんと使い分けてくれるし、書くときは

って書けばいいんですからすごく楽です。

 

一方で、contentsOfFile:を用いた場合は自動的に対応してくれません

こういう風に@3xの部分までちゃんと書かないと取得できません。

 

@2xと@3xちゃんと用意してあるのに〜〜〜この場合分けどうしたらいいんだ〜〜〜〜

そこでまず考えたのは画面サイズで判断とか、端末で判断とか・・・

 

でもちゃんとうってつけのがありました。

これで判断ができます。

 

とりあえず定数で@2x@3xの部分を作っちゃいました。

CGFloatなのでIntにしてStringにしてって忙しいですが、

でもこれで一応両対応できます。

 

ワ─+。:.゚ヽ(*´∀`)ノ゚.:。+゚─イ♪

 

どこのディレクトリに入ってるかによってまた変わってくると思います。

その辺も自分のプロジェクトに合わせてやればおkです。

なかなか上手くいかなくて、下記の記事を参考にさせていただきました。

[Swift3] Bundle.main.path が nil を返すときに確認すること

 

ヌゥン。

一応nil判定もしておいた方が良いのかしら・・・

 

結局私の場合はimagesディレクトリに入っているはずでimages/imageにしていたのですが、何故かうまくいかず、imageだけにするとできました。あとは@3xとかちゃんとつけてやるとできました。

 

これだけでも結構メモリに優しくできる気がします。

このUIImage解放されてなくない?と思ったらぜひ試してみてください。

 

 

魚ライン
モッピー!お金がたまるポイントサイト
魚ライン

日常の記事一覧を見る

コメント

コメントは認証制です。詳しくは下記の注意をお読みください。

コメントを残す

コメント時の注意

「Twitter」「Facebook」「Google+」「WordPress」のいずれかのアカウントをお持ちの方は各アカウントと連携することでコメントできます。 コメントしたことはSNSに流れませんので、アカウントをお持ちの方はこちらの方法でコメントを投稿して下さると嬉しいです。 アカウントをお持ちでない方はメールアドレスで投稿することができます。 初回コメント時は承認後に表示されます。

魚ライン 魚ライン