Re: Adding PDFPage to PDFDocument crashes
Re: Adding PDFPage to PDFDocument crashes
- Subject: Re: Adding PDFPage to PDFDocument crashes
- From: Paul Archibald <email@hidden>
- Date: Tue, 2 Sep 2008 12:47:56 -0700
Thanks for the comments Andy.
I see what you mean about reassigning that page pointer. As I recall,
I had trouble fully allocating a page without the pdf document. Just
using [[PDFPage alloc] init] did not seem to create a "real" pdf
page, and trying to do anything with such an object failed. I sort of
stumbled into this technique. Looking at the code, I think I could
also just forgo that pointer completely, and go with
PDFDocument *tempDoc = [[PDFDocument alloc] initWithData:[v
dataWithPDFInsideRect:r]];
//PDFPage *page = [[PDFPage alloc] initWithDocument:tempDoc]; // does
this copy the content of the doc to the page?
//page = [tempDoc pageAtIndex:0];
[outputDoc insertPage:[tempDoc pageAtIndex:0] atIndex:[outputDoc
pageCount]];
I am going to test this idea. Do you think that it would work? One
less pointer to manage?
Thanks again for your response.
Paul
On Sep 2, 2008, at 12:28 PM, Andy Mroczkowski wrote:
Hi Paul,
The structure of your code is very similar to some I wrote, which
works well for me.
A couple comments:
PDFDocument *tempDoc = [[PDFDocument alloc] initWithData:[v
dataWithPDFInsideRect:r]];
PDFPage *page = [[PDFPage alloc] initWithDocument:tempDoc];
page = [tempDoc pageAtIndex:0];
Here you're creating a PDFPage object and assigning it to the *page
pointer var. Then the *page pointer is being immediately re-
assigned to the first page of tempDoc. This is why the [page
autorelease] was blowing up. The PDFPage object was owned by
tempDoc, so it was being double released. Also, the PDFPage
initially alloc'd is being leaked. To fix it all, you just want to
do:
PDFDocument *tempDoc = [[PDFDocument alloc] initWithData:[v
dataWithPDFInsideRect:r]];
PDFPage *page = [tempDoc pageAtIndex:0];
I use the same strategy, which again, Works For Me.
Next:
[pdfpages autorelease]; // coments anyone?
[outputDoc autorelease]; // is this okay, or should I release
instead, or ...?
[view autorelease]; // if(alloced) release, right? isn't that
the rule?
Well first, pdfpages is no longer declared, but you probably knew
that =]
oops, yeah. what I pasted in is not exactly what I am using. I missed
that.
The other two autoreleases are correct, though in general I suggest
using regular release when you can. The overhead on autorelease
isn't much but it is non-zero. Plus it makes over-release bugs a
little harder to track down sometimes.
Point taken.
Happy Hacking =]
- Andy
Here is the working code, with the nonworking code commented out,
and some other comments, too:
//==========================================================
- (BOOL) renderToPDFFile: (NSArray*) textChunks :(NSString*) file {
// NSMutableArray *pdfpages = [[NSMutableArray alloc] init]; //
not using this anymore
NSRect r = NSMakeRect(0, 0, 600, 1);
NSTextView* view = [[NSTextView alloc] initWithFrame:r];
r = [view bounds];
PDFDocument *outputDoc = [[PDFDocument alloc] initWithData:[view
dataWithPDFInsideRect:r]];
int i;
for(i = 0; i < [textChunks count]; i++) {
NSTextView* v = [[NSTextView alloc] initWithFrame:r];
NSString *s = [textChunks objectAtIndex:i];
[v insertText:s];
[v sizeToFit]; // this is important for me
r = [v bounds]; // and it seems to work fine
PDFDocument *tempDoc = [[PDFDocument alloc] initWithData:[v
dataWithPDFInsideRect:r]];
PDFPage *page = [[PDFPage alloc] initWithDocument:tempDoc];
page = [tempDoc pageAtIndex:0];
[outputDoc insertPage:page
atIndex:[outputDoc pageCount]]; // this now works
// [pdfpages addObject:page]; // originally, I was trying to hold
on to the page objects in an array
// [page autorelease]; // << WOULD THIS BE CORRECT? My reading
of the
// mmgt stuff tells me yes, since the page is added to an
array, its refcount is incremmented,
// WAIT!! now it works without being released or
autoreleased. HELP!
// the rule says if I alloc it, I need to release it, so
what's correct? Am I leaking?
[tempDoc autorelease];
[v autorelease];
}
// id p;
// NSEnumerator *e = [pdfpages objectEnumerator]; // here I
intended to take each pdf page in the array and add it
// while(p = [e nextObject]) { // to the main pdf document
// [outputDoc insertPage:p // this was crashing. seemed to be
an array out of bounds error
// atIndex:[outputDoc pageCount]]; // but I could not decipher
the error message.
// }
[outputDoc removePageAtIndex:0]; // the first page was really a
dummy
NSData *data = [outputDoc dataRepresentation];
BOOL b = [data writeToFile:file atomically:YES]; // this works fine
[pdfpages autorelease]; // coments anyone?
[outputDoc autorelease]; // is this okay, or should I release
instead, or ...?
[view autorelease]; // if(alloced) release, right? isn't that
the rule?
return b;
}
If anyone has a few minutes to comment on this I would appreciate
it. Some aspects of Cocoa memory management are still odd to me,
like how to handle_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden