2

我正在尝试将视图的内容保存到 PDF 文件中。您看到的代码位于从 NSView 继承的类中:

- (IBAction) savePDF: (id) sender
{
    __block NSSavePanel* panel=[NSSavePanel savePanel];
    [panel setAllowedFileTypes: [NSArray arrayWithObject: @"pdf"]];
    [panel beginSheetModalForWindow: [self window] completionHandler: ^(NSInteger result)
     {
         if(result==NSOKButton)
         {
             NSCAssert(panel!=nil,@"panel is nil");
             NSData* data=[self dataWithPDFInsideRect: [self bounds]];
             NSError* error;
             BOOL successful=[data writeToURL: [panel URL] options: 0 error: &error];
             if(!successful)
             {
                 NSAlert* alert=[NSAlert alertWithError: error];
                 [alert runModal];
             }
         }
     }];
    panel=nil;
}

该方法由菜单触发。
问题是断言失败:

NSCAssert(panel!=nil,@"panel is nil");

即使我将 NSSavePanel 指针声明为 __block。为什么?

4

2 回答 2

2

实际上,答案是删除说明__block符。

我在有/没有它的情况下运行了你的代码。断言失败,没有它(即__block说明符)工作。

现在,回答为什么:

我想说明__block符是为全局/实例变量而不是局部变量制作的,不过我可能是错的。


X'D ...我不知道是什么击中了我,但请检查一下:

NSSavePanel* panel=[NSSavePanel savePanel];

[panel setAllowedFileTypes: [NSArray arrayWithObject: @"pdf"]];
[panel beginSheetModalForWindow: [self window] completionHandler: ^(NSInteger result)
 {
     if(result==NSOKButton)
     {
         dispatch_async(dispatch_get_main_queue(), ^{
             NSCAssert(panel!=nil,@"panel is nil");
             NSData* data=[self dataWithPDFInsideRect:[self bounds]];
             NSError* error;
             BOOL successful=[data writeToURL: [panel URL] options: 0 error: &error];
             if(!successful)
             {
                 NSAlert* alert=[NSAlert alertWithError: error];
                 [alert runModal];
             }
         });
     }
 }];
panel=nil;

我刚刚决定,让我将它包装在一个 GCD 块中,然后在主线程上绘制它。您的代码运行良好。该视图正在按预期绘制到 PDF,我可以确认:D。

至于这个问题,似乎很明显。在后台线程和绘图中调用边界是禁止的。

这很有趣,谢谢:D

于 2012-08-05T03:09:02.270 回答
1

解决方案:由于未知原因,这对我来说仍然是一个谜,如果我对视图类进行 IBAction,[self bounds] 总是返回 NSZeroRect。在其他方法中它返回正确的值。所以我解决了这个问题,删除来自 NSSavePanel 的 __block 说明符并重写(也重新绑定)应用程序委托类中的方法。

于 2012-08-05T12:44:34.727 回答