Cocoa:如何在执行后台任务时运行模态窗口?

Nic*_*kkk 2 macos cocoa modal-dialog

我试过打电话

modalSession=[NSApp beginModalSessionForWindow:conversionWindow];
[NSApp runModalForWindow:conversionWindow];
Run Code Online (Sandbox Code Playgroud)

为了获得一个modal conversionWindow,它阻止用户与应用程序的其余部分进行交互,但这似乎也阻止了代码的执行.我的意思是在上面显示的代码之后的代码根本不执行.我怎样才能解决这个问题?我确信这是可能的,因为许多应用程序在执行一些重要任务时表现出一些进展,例如视频转换等......

Rob*_*ger 7

除非绝对必要,否则请不要使用app-modal窗口.如果可能,请使用表格.但是,如果必须使用模态对话框,则可以在模式对话框打开时通过给它一些时间来运行主运行循环:

NSModalSession session = [NSApp beginModalSessionForWindow:[self window]];
int result = NSRunContinuesResponse;

while (result == NSRunContinuesResponse)
{
    //run the modal session
    //once the modal window finishes, it will return a different result and break out of the loop
    result = [NSApp runModalSession:session];

    //this gives the main run loop some time so your other code processes
    [[NSRunLoop currentRunLoop] limitDateForMode:NSDefaultRunLoopMode];

    //do some other non-intensive task if necessary
}

[NSApp endModalSession:session];
Run Code Online (Sandbox Code Playgroud)

如果您有需要主运行循环操作的视图(WebView请记住),这非常有用.

但是,要理解模态会话就是这样,并且在模式窗口关闭并且模态会话结束之前,调用之后的任何代码beginModalSessionForWindow:都不会被执行.这是不使用模态对话框的一个很好的理由.

请注意,您不能while在上面的代码中循环执行任何重要工作,因为这样您将阻止模态会话以及主运行循环,这将使您的应用程序变成沙滩球城市.

如果你想在后台做一些实质性的事情,你必须使用某种形式的并发,例如使用NSOperation,GCD后台队列或只是普通的后台线程.