对于PDF阅读器,我想通过获取每个页面的“屏幕截图”并将它们保存到光盘来准备文档。第一种方法是
CGPDFDocumentRef document = CGPDFDocumentCreateWithURL((CFURLRef) someURL);
for (int i = 1; i<=pageCount; i++)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
CGPDFPageRef page = CGPDFDocumentGetPage(document, i);
...//getting + manipulating graphics context etc.
...
CGContextDrawPDFPage(context, page);
...
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
...//saving the image to disc
[pool drain];
}
CGPDFDocumentRelease(document);
这会导致大量内存在第一次运行循环(准备第一个文档)后似乎没有释放,但在其他运行中没有更多未释放的内存:
MEMORY BEFORE: 6 MB
MEMORY DURING 1ST DOC: 40 MB
MEMORY AFTER 1ST DOC: 25 MB
MEMORY DURING 2ND DOC: 40 MB
MEMORY AFTER 2ND DOC: 25 MB
....
将代码更改为
for (int i = 1; i<=pageCount; i++)
{
CGPDFDocumentRef document = CGPDFDocumentCreateWithURL((CFURLRef) someURL);
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
CGPDFPageRef page = CGPDFDocumentGetPage(document, i);
...//getting + manipulating graphics context etc.
...
CGContextDrawPDFPage(context, page);
...
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
...//saving the image to disc
CGPDFDocumentRelease(document);
[pool drain];
}
将内存使用量更改为
MEMORY BEFORE: 6 MB
MEMORY DURING 1ST DOC: 9 MB
MEMORY AFTER 1ST DOC: 7 MB
MEMORY DURING 2ND DOC: 9 MB
MEMORY AFTER 2ND DOC: 7 MB
....
但显然在性能方面倒退了一步。
当我在第一种情况下开始阅读PDF(稍后时间,不同的线程)时,不再分配内存(保持在25 MB),而在第二种情况下,内存最多可达20 MB(从7开始)。
在这两种情况下,当我删除CGContextDrawPDFPage(context, page);
行内存在所有文档准备期间和之后(几乎)常量为6 MB。
有人可以解释那里发生的事情吗?
答案 0 :(得分:4)
CGPDFDocument非常积极地缓存,你几乎无法控制它,除了 - 正如你所做的那样 - 释放文档并从磁盘重新加载它。
当您删除CGContextDrawPDFPage调用时没有看到大量分配的原因是Quartz懒惰地加载页面资源。当您只调用CGPDFDocumentGetPage时,所有发生的事情是它加载一些基本元数据,如边界框和注释(内存非常小)。
字体,图像等仅在您实际绘制页面时加载 - 但随后它们会在内部缓存中保留相对较长的时间。这意味着使渲染更快,因为页面资源通常在多个页面之间共享。此外,多次渲染页面(例如放大时)相当常见。您会注意到第二次呈现页面要快得多。