2011-05-04 41 views
16

与400多个页面中创建PDF文档,我使用下面的伪代码来生成PDF文档:无法在iOS

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

大问题!我期待看到解决方案。 – 2011-05-04 04:48:44

+0

为什么只需要在设备上创建一个大文档?为什么不将数据发送到服务器并在那里生成PDF文档? – 2011-05-04 05:02:57

+1

我个人不会考虑通过服务器处理数据,因为我不认为每个人都会在他们的iDevices上始终有互联网连接。 – 2011-05-04 08:28:17

回答

1

如果您分配的内存太多,您的应用程序将崩溃。为什么生成一个非常大的PDF是一个目标?你究竟在努力完成什么?

+0

用户将1500多页pdf文档导入到我的应用中,并使用该应用对其进行了修改并希望将其导出,但我的应用崩溃了... – 2011-05-04 08:20:33

+1

您能否以原始PDF格式开始,只更换已更改的页面? – 2011-05-12 18:19:14

6

既然你创建通过CGPDFContextCreateWithURL单个文档的整个事情在内存中举行,并追加到,一些常用的(虽然我不能肯定与iOS和CGPDFContextCreateWithURL说),需要一个完整的要保存的文件副本。即使没有前后问题,也不需要泄漏造成问题。

如果你是不是想捕捉一堆现有的UIKit绘制的东西 - 你的样品中似乎你不是 - 使用OS的印刷方法代替,它提供built-in support for printing to a PDFUIGraphicsBeginPDFContextToFile在添加页面时将页面写入磁盘,因此整个过程不需要一次保存在内存中。你应该能够以这种方式生成一个巨大的PDF。

+0

UIGraphicsBeginPDFContextToFile线程安全吗?它没有在文档中说,但我会试试看。非常感谢! – 2011-05-04 08:26:23

+0

看来它不太可能线程安全。从概述:“**重要:** UIKit类通常不是线程安全的,所有与图形相关的操作应该在应用程序的主线程上执行。” http://developer.apple.com/library/ios/#documentation/2DDrawing/Conceptual/DrawingPrintingiOS/GraphicsDrawingOverview/GraphicsDrawingOverview.html – 2011-05-04 08:32:34

+0

是的,我不希望它很长一段时间阻止主线程...所以这可能对我无效。叹。 – 2011-05-04 08:49:09

3

可能不是您想要听到的答案,而是从另一个角度来看它。

您能否认为它是设备的限制?首先检查PDF中的页数,如果它太大,则向用户发出警告。因此,优雅地处理它。

然后,您可以在此展开....

您可以构建在小的iDevice PDF文件,如果PDF太大,构造它的服务器端下一次的iDevice的净连接。

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; 
+0

我想生成超过60页的PDF,但会导致内存加大。 当我从GITHUB导入后尝试以上我看到很多像Xcode 7.3中的下面的错误----------------- MemoryMappedDataConsumer.m: 功能'munmap'的隐式声明是无效C99 在需要之前,必须从模块“Darwin.POSIX.sys.mman”中导入'munmap'的声明 使用未声明的标识符'PROT_WRITE''PROT_READ''MAP_SHARED'--------- – Sanju 2016-05-26 12:19:07

+0

尝试使用'#import ' – nielsbot 2016-05-27 04:35:57