同步呈现NSOpenPanel作为表格

时间:2015-02-12 12:53:57

标签: cocoa nsopenpanel

我的情况是文档文件依赖于指向另一个外部媒体文件的链接。打开文档时,我会检查引用的媒体文件是否可用,如果没有,则提示用户找到它。

由于在基于文档的应用程序中将NSOpenPanel显示为工作表非常有意义,我想这样做但是当前线程被阻止是至关重要的,因此在新媒体文件之前不能调用后续代码被选中。

我无法找到一种方法在屏幕上显示此NSOpenPanel作为工作表,同时阻止当前线程。只有[NSOpenPanel runModal]能够满足我的需求,但这显示为常规对话而非工作表。

似乎这应该是可能的......

2 个答案:

答案 0 :(得分:4)

警告:我假设您正在使用沙箱,NSOpenPanel& NSSavePanel基于伏都教 - 他们的行为往往因操作系统点释放,月亮阶段,房子里是否有蓝奶酪等等而变化,让他们正常行为可能需要很大的耐心。 (见this question for one person's recent pain。)是的,我在开玩笑 - 有点 - 但你已被警告

还在吗?

类似于以下两种情况的代码已知在某个时间点工作,在满月期间和午夜过后的素数秒。

所有代码只输入答案,预计错别字。

首先:

+ (NSInteger) myRunModal:(NSOpenPanel *)myPanel
        asSheetForWindow:(NSWindow *)myWindow
{
   [myPanel beginSheetModalForWindow:myWindow
                   completionHandler:^(NSInteger result)
                                     {
                                        [NSApp stopModalWithCode:result];
                                     }
   ];
   return [NSApp runModalForWindow:myWindow];
}

在调用beginSheetModalForWindow:之后,您的线程进入模态循环,仅处理窗口的事件。当完成处理程序被调用它执行时,它退出该模态循环并返回结果。

无论你做什么,不要尝试将其作为类别添加到NSOpen / SavePanel类中。这样会导致疯狂。记住他们是伏都教,不要以任何方式直接与他们混淆。

第二

使用信号量,一方面这看起来很明显,另一方面就会出现另一个僵局......

+ (void) myRunModal:(NSOpenPanel *)myPanel
   asSheetForWindow:(NSWindow *)myWindow
  completionHandler:(void (^)(NSInteger))myHandler
{
   // Use a semaphore to block thread till sheet is done
   dispatch_semaphore_t sema = dispatch_semaphore_create(0);
   [myPanel beginSheetModalForWindow:myWindow
                   completionHandler:^(NSInteger result)
                                     {
                                        myHandler(result);
                                        // Unblock caller
                                        dispatch_semaphore_signal(sema);
                                     }
   ];
   // Block until sheet completes
   dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}

这里你的线程等待信号量发出信号。如果系统想要在同一个线程上执行处理程序,那么您将陷入僵局。它会尝试吗?也许

但是,如果您可以安排代码使得需要调用NSOpenPanel的代码在一个线程上运行,那么安排beginSheetModalForWindow:在主线程上运行dispatch_semaphore_wait在你的线程上,你应该掌握一个强大的解决方案。

第三

是的我只说了两个,第三个选项是甚至不尝试

HTH

答案 1 :(得分:0)

NSProgressIndicator上有一个属性,说天气与否,它是不确定的。为了显示进度,您必须将其设置为否