PDF rendering crashes app Core Graphics
- by Felixyz
EDIT: The memory leaks turned out to be unrelated to the crashes. Leaks are fixed but crashes remain, still mysterious.
My (iPhone) app does lots of PDF loading and rendering, some of it threaded.
Sometime, it seems always after I flush a page cash after getting a memory warning, the app crashes with a bad access when trying to draw a pdf page stored in an NSData object. Here is one example trace:
#0 0x3016d564 in CGPDFResourcesGetResource ()
#1 0x3016d58a in CGPDFResourcesGetResource ()
#2 0x3016d94e in CGPDFResourcesGetExtGState ()
#3 0x3015fac4 in CGPDFContentStreamGetExtGState ()
#4 0x301629a8 in op_gs ()
#5 0x3016df12 in handle_xname ()
#6 0x3016dd9e in read_objects ()
#7 0x3016de6c in CGPDFScannerScan ()
#8 0x30161e34 in CGPDFDrawingContextDraw ()
#9 0x3016a9dc in CGContextDrawPDFPage ()
But sometimes I get this instead:
Program received signal: “EXC_BAD_ACCESS”.
(gdb) bt
#0 0x335625fa in objc_msgSend ()
#1 0x32c04eba in CFDictionaryGetValue ()
#2 0x3016d500 in get_value ()
#3 0x3016d5d6 in CGPDFResourcesGetFont ()
#4 0x3015fbb4 in CGPDFContentStreamGetFont ()
#5 0x30163480 in op_Tf ()
#6 0x3016df12 in handle_xname ()
#7 0x3016dd9e in read_objects ()
#8 0x3016de6c in CGPDFScannerScan ()
#9 0x30161e34 in CGPDFDrawingContextDraw ()
#10 0x3016a9dc in CGContextDrawPDFPage ()
Is this an indication that I've mistakenly deallocated an object? It's hard for me to decode what's happening here.
This is how I create and retain the various objects involved:
// Some data was just loaded from the network and is pointed to by "data"
self.pdfData = data;
_dataProviderRef = CGDataProviderCreateWithData( NULL, [_pdfData bytes], [_pdfData length], NULL );
_documentRef = CGPDFDocumentCreateWithProvider(_dataProviderRef);
_pageRef = CGPDFDocumentGetPage(_documentRef, 1);
CGPDFPageRetain(_pageRef);
_pdfFrame = CGPDFPageGetBoxRect(_pageRef, kCGPDFArtBox);
So the NSData object is retained, and I explicitly retain the page reference. The data provider and the document are already retained by the create-functions.
And here is my dealloc method:
-(void)dealloc
{
if (_pageRef)
CGPDFPageRelease(_pageRef);
if (_documentRef)
CGPDFDocumentRelease(_documentRef);
if (_dataProviderRef)
CGDataProviderRelease(_dataProviderRef);
self.pdfData = nil;
[super dealloc];
}
Am I doing anything wrong? Even an assurance that I'm not, with explanation, would be a help.