Cannot create PDF document with 400+ pages on iOS

北城以北 提交于 2019-11-27 22:52:48

Since you're creating a single document via CGPDFContextCreateWithURL the entire thing has to be held in memory and appended to, something that commonly (though I can't say for certain with iOS and CGPDFContextCreateWithURL) requires a full before and after copy of the document to be kept. No need for a leak to create a problem, even without the before-and-after issue.

If you aren't trying to capture a bunch of existing UIKit-drawn stuff -- and in your sample it seems that you're not -- use the OS's printing methods instead, which offer built-in support for printing to a PDF. UIGraphicsBeginPDFContextToFile writes the pages out to disk as they're added so the whole thing doesn't have to be held in memory at once. You should be able to generate a huge PDF that way.

Probably not the answer you want to hear, but looking at it from another perspective.

Could you consider it as a limitation of the device?... First check the number of pages in the PDF and if it is too large, give a warning to the user. Therefore handling it gracefully.

You could then expand on this....

You could construct small PDF's on the iDevice and if the PDF is too large, construct it server-side the next time the iDevice has a net connection.

If you allocate too much memory, your app will crash. Why is generating an unusually large PDF a goal? What are you actually trying to accomplish?

What about using a memory mapped file to back your CG data consumer? Then it doesn't necessarily have to fit in RAM all at once.

I created an example here: https://gist.github.com/3748250

Use it like this:

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;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!