Cocoa: how to run a modal window while performing a background task?

六眼飞鱼酱① 提交于 2019-12-01 01:37:05
Rob Keniger

Please don't use an app-modal window unless it's absolutely necessary. Use a sheet if possible. However, if you must use a modal dialog, you can make the main run loop run by giving it some time while the modal dialog is open:

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];

This is very useful if you have views that require the main run loop to operate (WebView comes to mind).

However, understand that a modal session is just that, and any code after the call to beginModalSessionForWindow: will not be executed until the modal window closes and the modal session ends. This is one very good reason not to use modal dialogs.

Note that you must not do any significant work in the while loop in the code above, because then you will block your modal session as well as the main run loop, which will turn your app into beachball city.

If you want to do something substantial in the background you must use some form of concurrency, such as a using NSOperation, a GCD background queue or just a plain background thread.

You need to start the background "task" in another thread if you want it to run while a modal window is up. But in most cases, the best solution is to not use a modal window.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!