更改打印面板设置时 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;
}
DeductionTablePrintViewController
是 NSViewController
的子类,严格用于打印。有对应的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;
}
Here is the 'before' screenshot,正确填充了打印预览中的 table 数据(以及打印输出)。
Here is the 'after' screenshot,单击 "Pages: From to " 单选按钮后,打印预览中的 table 数据(以及打印输出中的数据)消失了。
正如上面 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
发送消息。
我正在尝试通过自定义 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;
}
DeductionTablePrintViewController
是 NSViewController
的子类,严格用于打印。有对应的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;
}
Here is the 'before' screenshot,正确填充了打印预览中的 table 数据(以及打印输出)。
Here is the 'after' screenshot,单击 "Pages: From to " 单选按钮后,打印预览中的 table 数据(以及打印输出中的数据)消失了。
正如上面 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
发送消息。