更改打印面板设置时 NSTableView 数据消失

NSTableView data disappears when print panel settings are changed

我正在尝试通过自定义 NSView 打印 NSTableView 中填充的数据。当用户发出打印命令时,包含 NSTableView 的自定义 NSView 按预期显示在打印面板中

我遇到的问题如下:如果用户更改打印面板中的任何设置,填充 NSTableView 的数据将被清空。如果用户单击打印,也会发生同样的事情。我的问题:当用户与打印面板交互时,如何使数据不消失?

附加信息: (1) NSView 中的标签按预期显示,并且 (2) 如果我绕过打印面板,通过发出 [printOp setShowsPrintPanel:NO]; [printOp runOperation]; NSTableView 中的数据按预期打印。

推测: 我正在更新我的程序以使用自动引用计数 (ARC)。似乎指向数据的指针被提早释放,这样当用户与打印面板交互时,数据不再可用于 NSView;但我无法确定发生这种情况的位置(据我所知,在首次显示打印面板后,我的代码未被访问)。

如有任何帮助,我们将不胜感激。谢谢你。附件是一些有助于诊断的代码。

来自MyDocument.m(NSDocument的子类),开始打印操作的代码:

-(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;
}

DeductionTablePrintViewControllerNSViewController 的子类,严格用于打印。有对应的xib文件。来自 DeductionTablePrintViewController.h(连接到 xib:

IBOutlet DeductionTable *deductionTable;

现在 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;
}

正如上面 Willeke 所建议的(谢谢),ARC 正在释放视图控制器。解决方案是添加到 MyDocument.h:

DeductionTablePrintViewController *pvc;

然后将方法 printOperationWithSettings 更改为:

-(NSPrintOperation *)printOperationWithSettings:(NSDictionary *)ps error:(NSError **)e
{
    pvc = [[DeductionTablePrintViewController alloc] initWithScopeDeduction:deduction andHelper:helper andDeductionController:self];
    .... ....
}

一旦引用对象不再被释放,打印面板就会按预期工作。

附加信息:这个问题的一个有趣的方面是视图控制器在打印面板出现后被释放,所以面板有时间创建打印预览,但随后无法访问 table 的数据。此外,我认为公式、推导标识符和 table 视图(见上图)在视图控制器被释放后仍然出现的原因是,一旦它们被绘制到视图上,打印对话框就不会尝试重绘他们。但是打印面板通过调用 tableView:objectValueForTableColumn:row 重复读取 table 的数据。诊断此问题的进一步令人沮丧的尝试是两件事:(i)当打印面板在已释放的视图控制器上调用 tableView:objectValueForTableColumn:row 时,没有发出警告或错误,而是静默失败; (ii) 当我在 tableView:objectValueForTableColumn:row 中插入断点时,调试器会在向用户显示打印面板之前中断,但不会在视图控制器被解除分配后中断。后一种行为是有道理的,因为它已被释放并且代码不能是 运行;但这让我相信打印面板在初始设置中只向 tableView:objectValueForTableColumn:row 发送消息。