CGContextDrawPDFPage内存泄漏 – 应用程序崩溃
当我用仪器分析我的应用程序时,我发现CGContextDrawPDFPage
分配的数据不会立即释放。 应用程序因CGContextDrawPDFPage
而崩溃。
你好,这里是我在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, 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); }
这是devise。 为了更快的重绘,CGPDFDocumentRefcaching页面资源。
清空caching的唯一方法是释放并重新打开CGPDFDocumentRef。