Reputation: 178
I've got some memory issue on a simple iPad/iPhone app that should display a (large) PDF. Here is what I do.
I've got a scrollView with 5 subviews. Each subview displays a page of my PDF. One page is always displayed, 2 pages on each side are preloaded. If you scroll, a no-more-needed view is taken, the new PDF page to preload is rendered and the view is repositioned inside the scrollView.
Everything works really fine except that memory issue. If I profile memory leaks, the live bytes grow from 4MB to 40MB+. The overall bytes grow up to 600 MB+. I think the live bytes should not really grow, as I have the same 5 views at any time. Or am I reading the values incorrect?
ARC is used.
This is the code that renders the PDF pages.
-(void)drawRect:(CGRect)inRect{
self.ctx = UIGraphicsGetCurrentContext();
CGContextSaveGState(self.ctx);
CGRect cropBox = CGPDFPageGetBoxRect(self.pdfPage, kCGPDFCropBox);
CGRect targetRect = [self bounds];
CGFloat xScale = targetRect.size.width / cropBox.size.width;
CGFloat yScale = targetRect.size.height / cropBox.size.height;
CGFloat scaleToApply = xScale < yScale ? xScale : yScale;
CGFloat newWidth = cropBox.size.width * scaleToApply;
CGFloat newHeight = cropBox.size.height * scaleToApply;
CGFloat xOffset = (targetRect.size.width - newWidth) / 2;
CGFloat yOffset = (targetRect.size.height - newHeight) / 2;
CGContextTranslateCTM(self.ctx, xOffset, [self bounds].size.height - yOffset);
CGContextScaleCTM(self.ctx, 1.0, -1.0);
CGContextConcatCTM(self.ctx, CGAffineTransformMakeScale(scaleToApply, scaleToApply));
CGContextSetInterpolationQuality(self.ctx, kCGInterpolationHigh);
CGContextSetRenderingIntent(self.ctx, kCGRenderingIntentDefault);
CGContextDrawPDFPage(self.ctx, self.pdfPage);
CGContextRestoreGState(self.ctx);
}
And this is the method that makes the view rerender to a new PDF page, if the old is no more needed.
- (void)redrawPdfPage:(CGPDFPageRef)pPdfPage withPageNum:(int)pPageNum {
self.pdfPage = pPdfPage;
self.pageNum = pPageNum;
CGRect r = [self frame];
r.origin.x = r.size.width * (self.pageNum - 1);
[self setFrame:r];
[self setNeedsDisplay];
}
Any advice on this will be appreciated, as I'm trying to figure out how to free the memory of the old PDF pages for days...
Upvotes: 0
Views: 264
Reputation: 7944
With ARC you still have to put some effort into managing Foundation objects. You can release old page using CGPDFPageRelease
. Or you can add appropriate attribute to your pdfPage
property declaration, as described in this answer.
Upvotes: 1