I am trying to print data populated in an NSTableView
through a custom NSView
. When the print command is issued by the user, the custom NSView
containing the NSTableView
is shown in the Print Panel as expected
The problem I am encountering is as follows: if the user changes any settings in the Print Panel, the data populating the NSTableView
is blanked out. The same thing happens if the user clicks Print. My question: how do I make the data not disappear when the user interacts with the Print Panel?
Additional Information: (1) There are labels in the NSView
that appear as expected, and (2) If I bypass the Print Panel, by issuing [printOp setShowsPrintPanel:NO]; [printOp runOperation];
the data in the NSTableView
prints as expected.
Speculation: I am in the process of updating my program to use Automatic Reference Counting (ARC). It almost seems as if the pointer to the data is being released early, such that when the user interacts with the Print Panel the data is not longer available to the NSView
; but I am not able to determine where that happens (my code is not being accessed, as far as I can tell, after the Print Panel is first presented).
Any help would be greatly appreciated. Thank you. Attached is some of the code to help in diagnosis.
From MyDocument.m (subclass of NSDocument
), the code that kicks off the print operation:
-(NSPrintOperation *)printOperationWithSettings:(NSDictionary *)ps error:(NSError **)e
{
DeductionTablePrintViewController *pvc = [[DeductionTablePrintViewController alloc] initWithScopeDeduction:deduction andHelper:helper andDeductionController:self];
NSPrintInfo *printInfo = [self printInfo];
NSRect viewFrame = [[pvc view] frame];
viewFrame.size.width = [printInfo imageablePageBounds].size.width;
[[pvc view] setFrame:viewFrame];
NSPrintOperation *printOp = [NSPrintOperation printOperationWithView:[pvc view] printInfo:printInfo];
return printOp;
}
DeductionTablePrintViewController
is a subclass of NSViewController
used strictly for printing. There is a corresponding xib
file. From DeductionTablePrintViewController.h
(hooked up to the xib
:
IBOutlet DeductionTable *deductionTable;
Now for DeductionTablePrintViewController.m
:
-(id)initWithScopeDeduction:(ScopeDeduction *)aDeduction andHelper:(DeductionHelper *)aHelper andDeductionController:(MyDocument *)aDeductionController
{
self = [super initWithNibName:@"DeductionTablePrintView" bundle:nil];
if (self) {
// Set deduction
deduction = [aDeduction copy]; // Deep copy
deductionController = aDeductionController; // MyDocument
[[(DeductionTablePrintView *)[self view] deductionTable] setDeduction:deduction];
}
return self;
}
-(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)row
{
id objectValue = nil;
// objectValue is calculated here
... ... ...
return objectValue;
}
Here is the 'before' screenshot, with the table data in the print preview (and from here, the print output) being properly populated.
Here is the 'after' screenshot, with the table data in the print preview (and from here, the print output) having disappeared after clicking the "Pages: From to " radio button.
The view controller was being deallocated by ARC, as suggested by Willeke above (thank you). The solution was to add to MyDocument.h:
DeductionTablePrintViewController *pvc;
And then changing the method printOperationWithSettings
to read:
-(NSPrintOperation *)printOperationWithSettings:(NSDictionary *)ps error:(NSError **)e
{
pvc = [[DeductionTablePrintViewController alloc] initWithScopeDeduction:deduction andHelper:helper andDeductionController:self];
.... ....
}
Once the referent was no longer being deallocated, the Print Panel worked as expected.
Additional Information: An interesting aspect of this problem is that the view controller was deallocated after the Print Panel appeared, so the panel had time to create a print preview, but then did not have access to the data for the table. Also, I think the reason the formula, deduction identifier, and tableview (see pictures above) still appear after the view controller was deallocated was that the once they were drawn onto the view the Print Dialog did not try to redraw them. But the Print Panel repeatedly reads in data for the table with calls to tableView:objectValueForTableColumn:row
. Further frustrating attempts to diagnose this problem were two things: (i) when the Print Panel calls tableView:objectValueForTableColumn:row
on a deallocated view controller, no warning or error is issued, but instead fails silently; (ii) when I inserted a breakpoint in tableView:objectValueForTableColumn:row
the debugger breaks before the Print Panel is shown to the user but not once the view controller is deallocated. This latter behaviour makes sense, since it is deallocated and the code cannot be run; but this led me to believe the Print Panel only sent messages to tableView:objectValueForTableColumn:row
in the initial setup.