Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception releasing context after CGContextDrawPDFPage only for some pages

I've inherited some iOS code which opens a source PDF and creates a CGContextRef to which we draw a single page from the source document. The problem is that there are certain pages with one document, our help document unfortunately, which causes this code to crash.

The end goal is to cache 8 pages at a time to improve the user experience.

CFMutableDataRef consumerData = CFDataCreateMutable(kCFAllocatorDefault, 0);
CGDataConsumerRef contextConsumer = CGDataConsumerCreateWithCFData(consumerData);

CGPDFPageRef page = CGPDFDocumentGetPage(sourceDocument, pageNumber);

const CGRect mediaBox = CGPDFPageGetBoxRect(page, kCGPDFCropBox);
CGContextRef pdfOutContext = CGPDFContextCreate(contextConsumer, &mediaBox, NULL);

CGContextDrawPDFPage(pdfOutContext, page); //If I comment out this line, no exception occurs

CGPDFPageRelease(page);
CGPDFContextEndPage(pdfOutContext);

CGPDFContextClose(pdfOutContext); //EXC_BAD_ACCESS
CGContextRelease(pdfOutContext);

(This is a simplified version of the code, the original opens a source document and a page, checks for null on page and ctx, and then writes ctx to a new document.)

There's no issue if, instead of drawing to a PDF context, I draw to a UIGraphics context created thusly:

CGContextRef graphicsContext = UIGraphicsGetCurrentContext();

There is also no issue when I draw other things to the PDF context.

Plus, this works for 99% of the documents and for 75% of the pages within the offending document. The offending document renders correctly in several PDF viewers.

So I don't think there's a memory issue on my part. I'm fairly confident that there is something within the CGPDF code that is buggy (and I say that only after spending a week trying to resolve this issue).

My question is, is there some other way I should/could be doing this?

like image 333
Robert Gowland Avatar asked Nov 13 '22 14:11

Robert Gowland


1 Answers

There is enough evidence that this is a bug introduced in iOS5 for us to work around the issue rather than trying to solve it. So we ended up removing the caching. It's only marginally slower on an iPad 1 than it was with caching for a 200 page document, so the product manager decided that was acceptable (when compared to simply crashing).

We also tried writing the doc to an image and displaying that, but it wasn't any faster and produced a result of inferior quality (especially when zooming).

EDIT

Submitted the bug to Apple. It turns out to have already been reported. The original bug is 10428451 and is being looked at by their engineers.

like image 190
Robert Gowland Avatar answered Nov 16 '22 04:11

Robert Gowland