iPadアプリ作成日記: 「iPadアプリ作ってて良かったなあ」と思える瞬間
「金メダリストは『練習が楽しくてしかたがない』からこそ強くなれた」説

iPadアプリ作成日誌: PDF関連APIのバグについて

 以前にもここで少し触れたiPhone OSのPDF関連APIのバグについての詳しい情報が知りたいという連絡がTwitter経由で入ったが、140文字制限でするのもなんなので、具体的にバグレポートを書いてみる。

 iPhone OS 上でPDFファイルを表示する場合、まずは CGPDFDocumentCreateWithURL でドキュメントを開く必要がある。CloudReadersの場合はこんな感じだ。

        NSURL* url = [NSURL fileURLWithPath:path];

        CGPDFDocumentRef doc = CGPDFDocumentCreateWithURL((CFURLRef)url); 

count = CGPDFDocumentGetNumberOfPages(doc);

 特定のページを表示(=描画)する際には、CGPDFDocumentGetPage でページハンドルを取得し、CGContextDrawPDFPage で描画する。

        CGPDFPageRef page = CGPDFDocumentGetPage(doc, i);
        CGContextDrawPDFPage(context, page);

 くせ者はこの CPDFDocumentGetPage。すべてベクター(文字も含む)で書かれたPDFドキュメントの場合、何の問題もないのだが、スキャナーで作ったPDFの場合、大量のメモリーを消費するのだ(手持ちのサンプルだと1ページあたり26MB!)。

 それも一時的なものであれば良いのだが、なぜか次のページを描画してもそのメモリは解放されず、そのまま数ページ進むとメモリ不足でアプリが落ちてしまう。

 以前、Appleのフォーラムで何人かの人がこの問題を指摘したところ、そのメモリーは CGPDFDocumentRelease を呼べば解放されるので、メモリーリークではなく「高速化のための単なるキャッシュ」という返事がAppleの担当者から返って来た。その人に言わせると、「メモリを節約したいのであれば、「1ページ描画するごとにドキュメントを開いて閉じれば良い」ということ。

 私から見れば、これはメモリがふんだんにあるOSXのコードをそのままiPhone OSに持って行ったために生じた不具合である。3〜4ページ描画しただけでアプリが落ちてしまうのだから、十分にバグと呼べると思う。

 これが原因で、iPhone/iPad向けのPDFリーダーは、画像ばかりのPDFファイルを開くとメモリ不足で落ちたり、妙に遅くなったりするのだ。CloudReadersの場合、まずはスピード優先で走り、メモリ不足が生じた時点で「Safe Mode」に移行するという綱渡り的なコーディングでしのいでいる。1.04から落ちにくくなったのはそのため。


Comments

Verify your Comment

Previewing your Comment

This is only a preview. Your comment has not yet been posted.

Working...
Your comment could not be posted. Error type:
Your comment has been posted. Post another comment

The letters and numbers you entered did not match the image. Please try again.

As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

Having trouble reading this image? View an alternate.

Working...

Post a comment

Your Information

(Name is required. Email address will not be displayed with the comment.)