1

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

我遇到的问题如下:如果用户更改打印面板中的任何设置,填充的数据将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;
}
4

1 回答 1

0

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

DeductionTablePrintViewController *pvc;

然后将方法更改printOperationWithSettings为:

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

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

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

于 2017-05-14T01:55:09.527 回答