私は、collectionviewを使ってpdfReaderを作成したいと考えています。私が望むのは、pdfのサムネイルを表示するcollectionviewを持つことです。だから私はviewDidLoadでこれを使用します(実際には、私たちが上または下に行くたびにcollectionviewでサムネイルを生成しないようにします)。これは、1時間に生成され、それが遅れずに次のとおりです。PDFのサムネイルを生成してCollectionViewの画像をプリロードする方法は?
のviewDidLoadでPDFのサムネイルロード:
:サムネイルを使用して- (UIImage *)imageFromPDFWithDocumentRef:(CGPDFDocumentRef)documentRef
{
CGPDFPageRef pageRef = CGPDFDocumentGetPage(documentRef, 1);
CGRect pageRect = CGPDFPageGetBoxRect(pageRef, kCGPDFCropBox);
UIGraphicsBeginImageContext(pageRect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, CGRectGetMinX(pageRect),CGRectGetMaxY(pageRect));
CGContextScaleCTM(context, 1, -1);
CGContextTranslateCTM(context, -(pageRect.origin.x), -(pageRect.origin.y));
CGContextDrawPDFPage(context, pageRef);
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return finalImage;
}
:サムネイルを生成
- (void)viewDidLoad
...
coverPdf = [NSMutableArray new];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) {
// Load image on a non-ui-blocking thread
NSString *pdfPath = nil;
NSURL *pdfUrl = nil;
CGPDFDocumentRef pdfRef = nil;
NSMutableArray *arr = [NSMutableArray new];
for (id cover in filePathsArray)
{
pdfPath = [categoryPath stringByAppendingPathComponent:cover];
pdfUrl = [NSURL fileURLWithPath:pdfPath];
pdfRef = CGPDFDocumentCreateWithURL((CFURLRef)pdfUrl);
[arr addObject:[self imageFromPDFWithDocumentRef:pdfRef]];
NSLog(@"first process");
}
coverPdf = [NSMutableArray arrayWithArray:arr];
dispatch_sync(dispatch_get_main_queue(), ^(void) {
[pdfCollectionView reloadData];
});
});
...
}
を
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
ListPdfCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CollectionViewCell" forIndexPath:indexPath];
cell.productLabel.text = [filePathsArray objectAtIndex:indexPath.row];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) {
// Load image on a non-ui-blocking thread
dispatch_sync(dispatch_get_main_queue(), ^(void) {
// Assign image back on the main thread
if ([coverPdf count] > indexPath.row)
{
cell.pdfImage.image = [coverPdf objectAtIndex:indexPath.row];
}
});
});
return cell;
}
私はその方法に2つの問題があります:
- 最初は、サムネイルが表示されるまでに時間がかかりすぎることです。それがロードされると、うまく動作します。
- 第2の問題は、メモリが絶えず増加していることです。ビューコントローラを閉じても、メモリが解放されていないようです。私がviewcontrollerを閉じて9〜10回来たら、もしアプリケーションがクラッシュしたら。
結論として、pdfsのサムネイルをあらかじめ読み込んでコレクションビューを作成し、メモリが増加してクラッシュするのを避けるにはどうすればよいですか?
ありがとうございます。
SOLUTION:それは表示されるまで時間がかかりすぎているという事実のために
、私はちょうどDISPATCH_QUEUE_PRIORITY_HIGHでDISPATCH_QUEUE_PRIORITY_BACKGROUNDを置き換えます。はるかに良いです。メモリリークのために
、私はちょうどこのようなループの終わり、そして魔法のようにすべての作品でCGPDFDocumentRelease()関数を使用:
for (id cover in filePathsArray) { pdfPath = [categoryPath stringByAppendingPathComponent:cover]; pdfUrl = [NSURL fileURLWithPath:pdfPath]; pdfRef = CGPDFDocumentCreateWithURL((CFURLRef)pdfUrl); [arr addObject:[self imageFromPDFWithDocumentRef:pdfRef]]; CGPDFDocumentRelease(pdfRef);//Line added NSLog(@"first process"); }
ああ、私はCGPDFDocumentRelease(pdfRef)を使用します。バグのために完全に動作します。 – Claudio
@Claudioデフォルトで 'CGPDFDocumentGetPage'は自動解放されたオブジェクトを返します(Get semanticを持つ他のCGメソッドと同じように)。したがって、アップルによってバグが修正されると、手動でリリースすると余分なリリースが発生し、クラッシュする可能性があります。 –
問題を解決するときに削除します(私は個人的に解決しないと思います)。 – Claudio