2017-10-24 114 views
9

Uygulamamı Araçlar ile analiz ettiğimde, CGContextDrawPDFPage tarafından tahsis edilen verilerin hemen yayınlanmadığını öğrendim. Uygulama, CGContextDrawPDFPage nedeniyle kilitleniyor. CGContextDrawPDFPage bellek Kaçak - Uygulama Çökmesi

enter image description here

enter image description here

Merhaba burada CATiledlayer

Bu tasarım gereğidir
 - (void)drawLayer:(CATiledLayer *)layer inContext:(CGContextRef)context 
    { 
    if (_PDFPageRef == nil) { 
     return; 
    } 
    CGPDFPageRef drawPDFPageRef = NULL; 
    CGPDFDocumentRef drawPDFDocRef = NULL; 

    @synchronized(self) // Briefly block main thread 
    { 
     drawPDFDocRef = CGPDFDocumentRetain(_PDFDocRef); 
     if(_PDFPageRef != (__bridge CGPDFPageRef)([NSNull null])) 
      drawPDFPageRef = CGPDFPageRetain(_PDFPageRef); 
     else 
      return; 
    } 

    //CGContextSetRGBFillColor(context, 0.0f, 0.0f, 0.0f, 0.0f); 
    //CGContextFillRect(context, CGContextGetClipBoundingBox(context)); 

    if (drawPDFPageRef != NULL) // Render the page into the context 
    { 
     CGFloat boundsHeight = viewBounds.size.height; 

     if (CGPDFPageGetRotationAngle(drawPDFPageRef) == 0) 
     { 
      CGFloat boundsWidth = viewBounds.size.width; 

      CGRect cropBox = CGPDFPageGetBoxRect(drawPDFPageRef, kCGPDFCropBox); 
      int pageRotation = CGPDFPageGetRotationAngle(drawPDFPageRef); 

      CGSize pageVisibleSize = CGSizeMake(cropBox.size.width, cropBox.size.height); 
      if ((pageRotation == 90) || (pageRotation == 270) ||(pageRotation == -90)) { 
       pageVisibleSize = CGSizeMake(cropBox.size.height, cropBox.size.width); 
      } 

      float scaleX = boundsWidth/pageVisibleSize.width; 
      float scaleY = boundsHeight/pageVisibleSize.height; 
      float scale = scaleX < scaleY ? scaleX : scaleY; 

      // Offset relative to top left corner of rectangle where the page will be displayed 
      float offsetX = 0; 
      float offsetY = 0; 

      float rectangleAspectRatio = boundsWidth/boundsHeight; 
      float pageAspectRatio = pageVisibleSize.width/pageVisibleSize.height; 

      if (pageAspectRatio < rectangleAspectRatio) { 
       // The page is narrower than the rectangle, we place it at center on the horizontal 
       offsetX = (boundsWidth - pageVisibleSize.width * scale)/2; 
      } 
      else { 
       // The page is wider than the rectangle, we place it at center on the vertical 
       offsetY = (boundsHeight - pageVisibleSize.height * scale)/2; 
      } 

      CGPoint point = CGPointMake(offsetX, offsetY); 

      //CGRect cropBox = CGPDFPageGetBoxRect(drawPDFPageRef, kCGPDFCropBox); 
      int rotate = CGPDFPageGetRotationAngle(drawPDFPageRef); 

      //CGContextSaveGState(context); 

      // Setup the coordinate system. 
      // Top left corner of the displayed page must be located at the point specified by the 'point' parameter. 
      CGContextTranslateCTM(context, point.x, point.y); 

      // Scale the page to desired zoom level. 
      CGContextScaleCTM(context, scale , scale); 

      // The coordinate system must be set to match the PDF coordinate system. 
      switch (rotate) { 
       case 0: 
        CGContextTranslateCTM(context, 0, cropBox.size.height); 
        CGContextScaleCTM(context, 1, -1); 
        break; 
       case 90: 
        CGContextScaleCTM(context, 1, -1); 
        CGContextRotateCTM(context, -M_PI/2); 
        break; 
       case 180: 
       case -180: 
        CGContextScaleCTM(context, 1, -1); 
        CGContextTranslateCTM(context, cropBox.size.width, 0); 
        CGContextRotateCTM(context, M_PI); 
        break; 
       case 270: 
       case -90: 
        CGContextTranslateCTM(context, cropBox.size.height, cropBox.size.width); 
        CGContextRotateCTM(context, M_PI/2); 
        CGContextScaleCTM(context, -1, 1); 
        break; 
      } 

      // The CropBox defines the page visible area, clip everything outside it. 
      CGRect clipRect = CGRectMake(0, 0, cropBox.size.width, cropBox.size.height); 
      CGContextAddRect(context, clipRect); 
      CGContextClip(context); 

      CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0); 
      CGContextFillRect(context, clipRect); 

      CGContextTranslateCTM(context, -cropBox.origin.x, -cropBox.origin.y); 

      CGContextSetInterpolationQuality(context, kCGInterpolationHigh); 
      //    CGContextSetInterpolationQuality(context, kCGInterpolationMedium); 
      CGContextSetRenderingIntent(context, kCGRenderingIntentDefault); 

      if(context != nil && context != (__bridge CGContextRef)([NSNull null])) 
      { 
       CGContextDrawPDFPage(context, drawPDFPageRef); 
       //CGContextRestoreGState(context); 
      } 


     } 
     else // Use CGPDFPageGetDrawingTransform for pages with rotation (AKA kludge) 
     { 
      CGContextTranslateCTM(context, 0.0f, boundsHeight); CGContextScaleCTM(context, 1.0f, -1.0f); 

      CGContextConcatCTM(context, CGPDFPageGetDrawingTransform(drawPDFPageRef, kCGPDFCropBox, viewBounds, 0, true)); 
     } 

      //CGContextDrawPDFPage(context, drawPDFPageRef); 
    } 

    CGPDFPageRelease(drawPDFPageRef); // Cleanup 
    CGPDFDocumentRelease(drawPDFDocRef); 
} 

cevap

5

pdf çizim benim kodudur. Daha hızlı yeniden çizime izin vermek için CGPDFDocumentRef sayfa kaynaklarını önbelleğe alır.

Bu önbelleği boşaltmanın tek yolu, CGPDFDocumentRef'i serbest bırakmak ve yeniden açmaktır.