0

私は、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回来たら、もしアプリケーションがクラッシュしたら。
enter image description here 結論として、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"); 
        } 
    

答えて

1

私はあなたのための悪いニュースを持っています。メモリリークは問題ありませんが、iOS 10のメモリ管理のバグ

iOS 10.0.1および10.0.2ではCGContextDrawPDFPage()関数にメモリ管理のバグがあります。

あなたはここにhttp://www.openradar.me/28415289

また、あなたがこの議論にhttps://github.com/vfr/Reader/issues/166

を便利見つけることができますいくつかの単語での可能な回避策は CGPDFPageRef pageRef = CGPDFDocumentGetPage(documentRef, 1); を毎回作成するが、あなたのすべてのための1 CGPDFPageRefを使用しないで詳細を見つけることができますpdfファイル。あなたがそれをもう必要としないときは、それをNULLに設定します。サムネイルを作成

サムネイルを作成するための

溶液の面で遅れ。私はこのVCではやっていないことを示唆していますが、この.pdfがアプリケーションに追加された瞬間に、それぞれの.pdfのサムネイルを作成します(または、アプリケーションバンドルに保存されているすべてのpdfs )。次に、このプレビューをpdf名に等しい名前の.jpgまたは.pngファイルとして保存したり、アプリケーション内にあれば、任意のデータベースやその他のストレージ内のpdfとプレビューの関係を設定したりできます。 次に、コレクションビューでこのプレビューを再利用してください。

+0

ああ、私はCGPDFDocumentRelease(pdfRef)を使用します。バグのために完全に動作します。 – Claudio

+0

@Claudioデフォルトで 'CGPDFDocumentGetPage'は自動解放されたオブジェクトを返します(Get semanticを持つ他のCGメソッドと同じように)。したがって、アップルによってバグが修正されると、手動でリリースすると余分なリリースが発生し、クラッシュする可能性があります。 –

+0

問題を解決するときに削除します(私は個人的に解決しないと思います)。 – Claudio

関連する問題