我正在尝试将视图的内容保存为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?
答案 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类中的方法。