viewのframeサイズはできるだけ小さく


Mac Book Airを手に入れてから約2ヶ月半、なんとかアプリ第一弾をリリースすることができました。
足し算と引き算の算数アプリなんで特に難しいことはしていないように見えますが、全てが初めての経験なので本当にあちこちにつまずきました。

interface builderを横画面にする方法が分からなかったり、UINavigationViewの使い方なんてまったく意味が分かりませんでしたし、コピペしたコードもなぜか動かなかったり。ノウハウが全然ないからコピペして動かないと何がまずいのか全然わからない。
音の出し方もアニメーションのやり方も苦労しました。
そして最後の難関がアプリの申請作業。
申請作業ってちょっと大変過ぎでしょコレ。

そんなこんなでは苦労しましたが、その苦労のおかげでなんとかアプリの作り方のイメージができるようになり、やりたいことを実現するにはどうすればいいのか、なんとなく分かるようになってきました。

そして現在アプリ第二弾を作成中です。

作成中なのですが、今日までかなりハマっていた問題がありました。
メモリ不足でアプリが落ちてしまう問題です。


アプリのviewのイメージはこんな感じです。

写真をズーム表示したいので、UIScrollViewの上にUIImageViewを貼っています。
そして図では非常に分かりづらいですが、写真の上に図形を描くために、写真のサイズ分の2枚のUIViewをUIImageView上ではなく、UIScrollView上に貼っています。つまり2枚のUIViewとUIImageViewは兄弟view。

もしUIImageViewの上にUIViewを貼ると、ズームインしたときにUIView上に描いた図形やラベルなんかもズームされてしまいます。
これだと画像をズームイン/アウトしたときには、図形を描いている線も太くなったり細くなったりして。。。これはちょっとやりたいこととは違うんです。
やりたいのは、例えばUIView上に描いたのが三角形だとすると、三角形の線の太さはそのままで頂点の位置だけはズーム後の場所(写真上では一定の場所)に移動したい。

ということで、UIScrollViewの上にUIViewを貼ることにしました。
そして画像をズームしたあとのscrollViewDidEndZoomingの中で、UIViewのframeをズーム後のUIImageViewの大きさに合わせて再設定し、図形の頂点は再計算してsetNeedsDisplayで図形を再描画しています。
こうしておけばズームしてもUIView上の図形の線が太くなったり細くなったりすることもありません。

しかしここででてきたのが、最初に書いたメモリ不足でアプリが落ちてしまう問題です。
ズームインする前はUIView上の図形の形を変えたり動かしたりしてもスイスイ動くのですが、ズームインするととたんに動きが遅くなり、何個か図形を動かしたりすると落ちてしまいます。
ズームインすることでUIImageViewのframeサイズだけでなくUIViewのframeサイズも合わせて大きくなるのでこれがメモリを圧迫しているのか?
frameサイズなんて大きくしても大して問題ないのかと思っていましたが、巨大なサイズにdrawRectで図形を描くのには無理があるのか。。。図形を変形したり移動させたりするために、UIScrollViewのtouchesMovedが呼ばれる度にdrawRectで再描画してますし、かなりの負荷なのかなぁ?

viewの構成をガラッと変えるかなぁとかかなり悩みましたが苦肉の策として、UIViewのframeサイズはUIImageView全体のサイズに合わせるのではなく、図形を移動させたり変形させたりする度に図形を表示するために必要な最小のframeサイズを設定してやることにしてみました。
こうすればtouchesMovedが呼ばれたときにはこれまでの処理に加え、図形の形を調べてframeを再計算する処理とframeの再設定の処理が加わることになりますが、その代わり使用メモリは減るはずです。

どれくらいの改善効果があるのか、そもそもこの考え方で正常に動くのか心配でしたが実際にプログラムを書き換えてみると大成功でした。
ズームインした後でもかなり動作がスムーズになりましたし、メモリ不足で突然落ちてしまうこともなくなりました。
やはり巨大なframeを確保しておいたり巨大なframe全体を再描画するというのは相当にメモリを食っていたということですね。

大きな変更をしないでとりあえずは解決できて本当によかったです。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です