无法在iOS上创建400多页的PDF文档

时间:2011-05-04 04:27:23

标签: ios objective-c pdf pdf-generation quartz-graphics

我使用以下伪代码生成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创建在后台线程中完成。

4 个答案:

答案 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;