PDFサムネイル表示の例では全ページのサムネイルを作り終えるまで応答しなくなる、メモリ不足になっても回復不能でアプリが落ちるという問題があります。その改善策の例です。
@implementation WebViewWithThumnails
//行い、サムネイルイメージはセットしない。
- (void)addThumbnailsWithData:(NSData *)pdfData
{
//画面下にUIScrollViewを追加
_thumbnailScrollView =
[[ThumbnailScrollView alloc] initWithWebView:self height:80];
[_thumbnailScrollView addThumbnailViews:pdfData];
//この行を削除。
//[_thumbnailScrollView setPdfThumbnailImage:pdfData];
}
@implementation ThumbnailScrollView
//layoutSubviewsをオーバライドし、表示領域内にあるThumbnailViewに
//サムネイルイメージをセットする。
- (void)layoutSubviews
{
float x1 = self.contentOffset.x;
float x2 = x1 + self.frame.size.width;
NSMutableArray *views = [NSMutableArray arrayWithCapacity:16];
for(ThumbnailImageView *v in self.subviews) {
if ([v isMemberOfClass:[ThumbnailImageView class]]) {
if (v.frame.origin.x >= x1 - v.frame.size.width && v.frame.origin.x <= x2
&& v.subviews.count < 2) {
[views addObject:v];
}
}
}
//すぐにサムネイルを作らず、performSelector:withObject:afterDelay:でキュー
//に入れる。cancelPreviousPerformRequestsWithTarget:を呼ぶことで、
//に入れる。cancelPreviousPerformRequestsWithTarget:を呼ぶことで、
//layoutSubviewsが続けて呼ばれた場合に最後のものだけが実行される。
if (views.count > 0) {
[NSObject cancelPreviousPerformRequestsWithTarget:self];
[self performSelector:@selector(setImagesWithViewArray:) withObject:views afterDelay:0.1];
}
[super layoutSubviews];
}
- (void)setImagesWithViewArray:(NSArray *)views
{
//残りメモリが不足していたらメモリ空き容量を増やす。
//残りメモリ容量表示参照
if (_memMonitor.freeMemory < 50000000) {
[self removeThumbnailImages];
//十分メモリが空いたかわからないのでreturn。
//十分メモリが空いたかわからないのでreturn。
return;
}
//表示領域内のサムネイル画像を表示する。
//表示領域内のサムネイル画像を表示する。
for(ThumbnailImageView *v in views) {
CGPDFPageRef page = CGPDFDocumentGetPage(_pdf, v.pageNum);
[v setImageWithPdfPage:page];
}
}
//この例では既に作成されているサムネイル画像を全て解放する。
- (void)removeThumbnailImages
{
for(UIView *v in self.subviews) {
if ([v isMemberOfClass:[ThumbnailImageView class]]) {
[(ThumbnailImageView *)v removeThumbnailImage];
}
}
}