Освободить память, используемую CGContextDrawPDFPage - PullRequest
6 голосов
/ 07 марта 2011

Когда я анализировал свое приложение с помощью Instruments, я обнаружил, что данные, выделенные CGContextDrawPDFPage, не публикуются немедленно.Поскольку моя программа получает много «предупреждений памяти», я хотел бы освободить как можно больше памяти, но я не знаю, как освободить эту память.

Как вы можете видеть на http://twitpic.com/473e89/fullпохоже, что он связан с этим кодом

-(void)drawLayer:(CALayer*)layer inContext:(CGContextRef)ctx{
    NSAutoreleasePool * tiledViewPool = [[NSAutoreleasePool alloc] init];
    CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0);
    CGContextFillRect(ctx, CGContextGetClipBoundingBox(ctx));
    CGAffineTransform pdfTransform = CGPDFPageGetDrawingTransform([self.superview.superview getPage],kCGPDFMediaBox,tiledLayer.bounds, 0, true);
    CGContextSaveGState (ctx);
    CGContextTranslateCTM(ctx, 0.0, tiledLayer.bounds.size.height);
    CGContextScaleCTM(ctx, 1.0, -1.0);
    CGContextConcatCTM (ctx, pdfTransform);
    CGContextClipToRect (ctx, CGPDFPageGetBoxRect([self.superview.superview getPage],kCGPDFMediaBox));
    CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh);
    CGContextSetRenderingIntent(ctx, kCGRenderingIntentDefault);
    CGContextDrawPDFPage(ctx,[self.superview.superview getPage]);
    CGContextRestoreGState (ctx);
    UIGraphicsEndPDFContext();
    [tiledViewPool drain];
}

Я уже пытался обернуть вокруг него AutoReleasePool, но, похоже, это не имеет никакого влияния.Снимок экрана сделан после того, как TiledView (представление, к которому относится метод) освобожден.

Я надеюсь, что кто-то может помочь мне уменьшить использование памяти.

Ответы [ 2 ]

3 голосов
/ 11 марта 2011

Все, кого я знаю, кто когда-то имел дело с PDF-файлами на iOS, сталкивались с такой же проблемой.Похоже, единственное решение - выпустить документ и заново создать его.

Обратите внимание, что другая распространенная проблема заключается в том, что, пока вы выпускаете документ, CATiledLayer может одновременно визуализировать страницу из этого документа.Итак, вы должны хорошо использовать @synchronize (возможно, используя ваш pdfDocRef) и выпускать документ только после того, как плиточный слой завершит свою работу.

Кроме того, проверьте это: Fast and Lean PDF Viewerдля iPhone / iPad / iOs - советы и подсказки?

1 голос
/ 11 марта 2011

У меня была похожая проблема,

эта строка, которая получает страницу PDF

[self.superview.superview getPage]

Убедитесь, что вы открываете pdf каждый раз, когда извлекаете страницу, оказывается, CGPDFDocument очень хорошо обрабатывает память.

например. что-то вроде

//release the current pdf doc
 if(self.pdfDocumentRef!=nil){
   CGPDFDocumentRelease(self.pdfDocumentRef);
 }
 //open it again
 self.pdfDocumentRef=CGPDFDocumentCreateWithURL(..your url..);
 //pull out a page
 CGPDFPageRef pg = CGPDFDocumentGetPage(self.pdfDocumentRef, pageIndex+1);
...