NSSavePanel在完成处理程序块内部为nil

时间:2012-08-05 02:20:16

标签: objective-c cocoa osx-lion nssavepanel

我正在尝试将视图的内容保存为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.Why?

2 个答案:

答案 0 :(得分: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块中,并在主线程上绘制它。你的代码工作得非常好。该视图正如预期的那样被绘制,我可以确认:D。

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

这很有趣,谢谢:D

答案 1 :(得分:1)

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