加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ios – CGContextDrawPDFPage内存泄漏 – 应用崩溃

发布时间:2020-12-15 01:41:54 所属栏目:百科 来源:网络整理
导读:当我用Instruments分析我的应用程序时,我发现CGContextDrawPDFPage分配的数据不会立即释放.应用程序因CGContextDrawPDFPage而崩溃. 你好,这是我在CATiledlayer中绘制pdf的代码 - (void)drawLayer:(CATiledLayer *)layer inContext:(CGContextRef)context { i
当我用Instruments分析我的应用程序时,我发现CGContextDrawPDFPage分配的数据不会立即释放.应用程序因CGContextDrawPDFPage而崩溃.

enter image description here

enter image description here

你好,这是我在CATiledlayer中绘制pdf的代码

- (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);
    //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,cropBox.size.height);
                    CGContextScaleCTM(context,1,-1);
                    break;
                case 90:
                    CGContextScaleCTM(context,-1);
                    CGContextRotateCTM(context,-M_PI / 2);
                    break;
                case 180:
                case -180:
                    CGContextScaleCTM(context,-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,cropBox.size.height);
            CGContextAddRect(context,clipRect);
            CGContextClip(context);

            CGContextSetRGBFillColor(context,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,boundsHeight); CGContextScaleCTM(context,1.0f,-1.0f);

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

            //CGContextDrawPDFPage(context,drawPDFPageRef);
    }

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

解决方法

这是设计的.为了更快地重新绘制,CGPDFDocumentRef缓存页面资源.

清空此缓存的唯一方法是释放并重新打开CGPDFDocumentRef.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读