みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

UIImageView使用時のメモリ枯渇について

現在、パラパラ漫画を制作しているXcode初心者のものです。
初歩的な質問とは思いますが、いろいろと調べても自分で解決することが出来ず困っております。
どうぞご教授下さいますようお願い申し上げます。

本がめくれるように見せるため、ViewControllerにViewを設置し、そのViewの中にUiImageを配置して画像をUiImageに読み込むように制作しております。

また、Viewの部分をUIViewAnimationTransitionCurlUpによってページがめくれるようにしております。

画像は、事前にAllPagesという配列に読み込んでおります。
self.AllPages=[NSMutableArray array];
for (int i=1; i<=TotalPageAmount; i++) {
UIImage *image=[UIImage imageNamed:[NSString stringWithFormat:@"%@_%d",PrePageName,i]];
[AllPages addObject:image];
}

具体的な処理のソースと致しましては、以下の処理をタイマーによって呼び出して処理を行っております。
—————————————————————————————————————-
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.2];
[UIView setAnimationTransition:transition forView:self.ViewController cache:NO];
PageIndex++;
self.UiImage.image = [self.AllPages objectAtIndex:PageIndex];
[UIView commitAnimations];
—————————————————————————————————————-

メニューよりパラパラ漫画を数種類選べるようにしており、各漫画が200ページ(1枚の画像サイズは40kb程度)です。

これを実行すると、見れば見るほどメモリが使用されてしまいます。一度読み込んだものは、破棄されずそのままメモリに残っているように思われます。そのため、そのうちメモリワーニングが出てきてアプリが落ちてしまうという現象が起こっております。

ご教授いただくのに情報が不足している場合もあるかと存じますが、
どうぞ、ご指導くださいますようよろしくお願い申し上げます。

投稿日時 - 2014-08-25 22:40:20

QNo.8730449

困ってます

このQ&Aは役に立ちましたか?

9人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.2

アイデア1:Xcodeの新規プロジェクトで、PageBased Applicationテンプレートを選択する。
アイデア2:全画像からPDFを作成して、CoreGraphicsで処理する。

PDF Document Creation, Viewing, and Transforming
https://developer.apple.com/library/mac/documentation/graphicsimaging/conceptual/drawingwithquartz2d/dq_pdf/dq_pdf.html#//apple_ref/doc/uid/TP30001066-CH214-TPXREF101

アイデア3:「iBooks Author」(Apple提供。無償)を使って、ePub形式のブックを作成する。

https://itunes.apple.com/jp/app/ibooks-author/id490152466?mt=12

アイデア4:WebViewをベースにして、HTMLで、画像一枚ずつ読み込んで、表示する。

メモリ管理面まで、自前のプログラムで処理しようとすると、その開発だけで長期間を費やすでしょう。その面は、既存のAPIやフレームワークを流用することを考えたほうがいいし、そちらのほうが自前開発より有効な結果になるでしょう。

投稿日時 - 2014-08-26 01:52:30

お礼

ありがとうございました。
アイデア1を利用して、まずは作り直してみるようにいたします。
PageBased Applicationテンプレートが、そこまで有意義なものとは知らなかったので、早速今から作り直し、結果をご報告させていただきます。

取り急ぎ御礼のみですがまた、当該ページにメッセージを記載させていただきます。

投稿日時 - 2014-08-26 22:40:00

ANo.1

ソースコードは抜粋して載せるしかないのはわかりますが、
開示されていないところを推測するのに、ネーミングが
奇妙すぎるのか、よくわからないところがあります。

> [UIView setAnimationTransition:transition forView:self.ViewController cache:NO];

forViewに指定している「self.ViewController」って、
実際には何が入っているんでしょうか?
通常、イメージのアニメーションをするなら、
ここにはアニメーション対象となるUIImageViewクラスの
オブジェクトをを指定すると思うんですが、
その名前が「self.ViewController」なんですか?

> self.UiImage.image = [self.AllPages objectAtIndex:PageIndex];

これは切り替え先の新しいイメージを設定しているのだろうと思いますが、
「self.UiImage」は実際には何が入っているんでしょうか?
UiImageと書いているけど、実はUIImageクラスじゃなくて、
UIImageViewクラスですか?
もしそうだとしたら、前述のforViewパラメータにはself.UiImage
を指定することにならないのですか?

http://cocoadays.blogspot.jp/2010_09_01_archive.html
にあるように、forViewパラメータにはself.imageViewを指定し、
self.imageView.imageを更新するのが普通で、このように
作れば、とてもシンプルにわかりやすくできると思います。

メモリリークがあるとしたら、一番良くやりそうなのは、
何かイベントが発生するたびにaddSubviewする箇所があって、
同じviewがどんどん上に積み重なって行くケースです。
そのようにaddSubviewを何度もしてしまうようなコーディングは
ないですか?

あと気になるのは、タイマー間隔です。
ページめくりアニメーションは0.2秒で終わるようですが、
そのページめくり処理を呼び出すタイマー間隔は
0.2秒より大きく設定していますか?
このあたりは、大きくタイマー間隔をあけたもので
メモリ不足になるかどうか一度試して、タイマー間隔の
問題か否かを切り分けておいた方がよいと思います。

ソースコードを見てもメモリ不足になる原因がわからなければ、
xcodeにはInstrumentsという性能分析ツールがありますので、
その中のLeaksという機能を使えば、詳しいメモリ使用状況を見たり、
メモリリークの検出をしたりできます。活用することをお勧めします。
(参考)
http://blog.fenrir-inc.com/jp/2013/04/improve-mac-ios-apps-with-instruments.html

投稿日時 - 2014-08-26 00:45:12

お礼

ありがとうございました。ご指示いただいた内容でコーディングを行ってみました。
なお、記載したネーミングが理解づらく申し訳ございませんでした。
おっしゃっていただいたとおり、自分で勝手に複雑なView構成にしており、処理速度が圧倒的に速くなりました。
メモリの件については、まだ解決していないのですが、上記を踏まえた上で、再度検討をさせていただきます。

ありがとうございました。お礼申し上げます。

投稿日時 - 2014-08-26 22:37:18

あなたにオススメの質問