我使用以下伪代码生成PDF文档:
CGContextRef context = CGPDFContextCreateWithURL(url, &rect, NULL);
for (int i = 1; i <= N; i++)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
CGContextBeginPage(context, &mediaBox);
// drawing code
CGContextEndPage(context);
[pool release];
}
CGContextRelease(context);
它适用于小文档(N < 100
页面),但它使用太多
如果文档有超过400页(收到它),则内存和崩溃
在崩溃之前有两个内存警告。)我确保没有使用泄漏
仪器。您对在iOS上创建大型PDF文档有何建议?非常感谢。
编辑:pdf创建在后台线程中完成。
答案 0 :(得分:6)
由于您是通过CGPDFContextCreateWithURL
创建单个文档,因此整个内容必须保存在内存中并附加到通常的内容中(尽管我不能肯定地说iOS和CGPDFContextCreateWithURL
)要求保留文档的前的和 副本之后的完整。即使没有前后问题,也不需要泄漏来产生问题。
如果您没有尝试捕获一堆现有的UIKit绘制内容 - 并且在您的示例中似乎您不是 - 请使用操作系统的打印方法,而 {{3} } 即可。 UIGraphicsBeginPDFContextToFile
将页面写入磁盘,因为它们被添加,因此整个过程不必一次保存在内存中。你应该能够以这种方式生成一个巨大的PDF。
答案 1 :(得分:3)
可能不是你想听到的答案,而是从另一个角度看待它。
您是否可以将其视为设备的限制?...首先检查PDF中的页数,如果它太大,请向用户发出警告。因此,优雅地处理它。
然后你可以扩展这个....
您可以在iDevice上构建小PDF,如果PDF太大,则在下次iDevice具有网络连接时构建服务器端。
答案 2 :(得分:1)
如果您分配了太多内存,您的应用就会崩溃。为什么生成异常大的PDF目标?你到底想要完成什么?
答案 3 :(得分:1)
使用内存映射文件来支持CG数据使用者怎么样?然后它不一定必须同时适合RAM。
我在这里创建了一个示例:https://gist.github.com/3748250
像这样使用:
NSURL * url = [ NSURL fileURLWithPath:@"pdf.pdf"] ;
MemoryMappedDataConsumer * consumer = [ [ MemoryMappedDataConsumer alloc ] initWithURL:url ] ;
CGDataConsumerRef cgDataConsumer = [ consumer CGDataConsumer ] ;
CGContextRef c = CGPDFContextCreate( cgDataConsumer, NULL, NULL ) ;
CGDataConsumerRelease( cgDataConsumer ) ;
// write your PDF to context `c`
CGPDFContextClose( c ) ;
CGContextRelease( c ) ;
return 0;