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

解決済みの質問

iPadでpdfファイルを表示/拡大縮小する

現在、iOSのプログラミングを学習しています。
pdfファイルを表示したり、拡大縮小する事は出来たのですが、ページを移動するたびにLeaksで確認した結果、メモリが膨らんでしまい、どんどん処理が重くなり最終的にmemory warningで落ちてしまいます。

ZoomingPDFViewerViewControllerのrenew_pagesのreleaseが上手くいっていないのが原因でないかと考えてるのですが、retainCountがinitWithFrameでは1なのに対し、再度renew_pageが呼び出された時には2になっており、releaseを行っても参照カウンタが2→1になっている感じで、これが原因だと考えてます。

ただ、なぜ参照カウンタがinitWithFrame呼び出し終了時は1なのに対し、retain等を行っていないのに参照カウンタが2になっているかが分からない次第です。

大変ややこしい事で恐縮ですが、どう処理すれば、メモリを無駄に増やす事なくpdfの表示/拡大縮小が出来るかをお教え頂きたいです。

プロジェクトが入ったソースをアップローダーにあげてあります。(DLコード:4649)
http://ux.getuploader.com/praFla/download/186/pdf_reader.zip
(念のため、ウイルススキャンをお願いします)

投稿日時 - 2011-07-19 17:11:26

QNo.6885810

すぐに回答ほしいです

質問者が選んだベストアンサー

> releaseとremoveSuperViewを試してみたのですが、今度は画面の散らつきとランダムでアプリが終了する状態になりました。

リリースされたインスタンスに、アクセスしている状態ではないですか?

> 参照カウンタはremoveSuperView→releaseで2→0になり、nilを入れた後で再度同じ変数に対してinitWithFrameを使って再利用している状態です。

Retain Countが0を取得することはありえません。なぜなら、バッファを開放したインスタンスにアクセスしたら、それが「retainCount」メソッドであっても、例外が発生するからです。Retain Countが0を取得するのは、インスタンス変数にnilを代入した直後のみです。

Viewを生成したら、autoreleaseするか、addSubviewした直後にreleaseする。
removeFromSuperviewすると、autoreleaseしたのと同じ状態になるので、あとはAutorelease Poolが適切に開放処理してくれるのに任せる。
この2点をおさえておけば、ほかの処理は不要だし、よかれと思ったことが徒になる危険のほうが高くなるでしょう。

なお、autoreleaseすると、Retain Countは、意味のある数値を返さなくなります。値が1以上であっても、バッファが保持されていることを示しません。

投稿日時 - 2011-07-20 17:16:27

ANo.2

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

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

回答(2)

ANo.1

> ただ、なぜ参照カウンタがinitWithFrame呼び出し終了時は1なのに対し、retain等を行っていないのに参照カウンタが2になっているかが分からない次第です。

メソッド「renew_page」内で、「addSubview:」を行ったあとで、サブビューにreleaseを行っていませんね?

UIViewクラスのリファレンス「addSubview:」から引用:
Parameters
view
The view to be added. This view is retained by the receiver. After being added, this view appears on top of any other subviews.

addSubviewすると、Retain Countが1増えます。(removeFromSuperViewでは、Retain Countが1減ります)
なので、addSubviewしたViewは、直後releaseを送るか、あらかじめ「autorelease」しておきます。

これは、NSArrayクラスが要素を追加したとき、要素オブジェクトをRetainするというふるまいに起因します。そのことを理解しておけば、ぎゃくにうまくメモリ管理を行うテクニックとして使えるんじゃないですかね?

投稿日時 - 2011-07-19 18:19:36

補足

回答ありがとうございます。
addSubView後にreleaseするプログラムもあれば、しないプログラムもあったので盲点でした。

releaseとremoveSuperViewを試してみたのですが、今度は画面の散らつきとランダムでアプリが終了する状態になりました。
参照カウンタはremoveSuperView→releaseで2→0になり、nilを入れた後で再度同じ変数に対してinitWithFrameを使って再利用している状態です。

投稿日時 - 2011-07-20 09:52:12

あなたにオススメの質問