开发者

NSRunAlertPanel() outside of the main thread?

开发者 https://www.devze.com 2022-12-08 12:53 出处:网络
I\'ve stumbled upon a problem in the application I\'m developing using cocoa. I need to do some processing, and I\'m doing it on a separate thread. I\'m doing this so I can display the progress using

I've stumbled upon a problem in the application I'm developing using cocoa. I need to do some processing, and I'm doing it on a separate thread. I'm doing this so I can display the progress using a NSProgressIndicator and not hang the main thread. (The user can cancel the execution if he/she wants).

It's almost working perfectly, But there's a problem: The processing produces a lot of files, and if one or more of these files already exists, I would like to ask the user if it's OK to overwrite them before actually doing so. So I tried using NSRunAlertPanel() from the processing thread.

It works some of the times. Other times, the Alert Panel will flicker, close for no particular reason before I can click on it, or not appear at all. So I figured that NSRunAlertPanel() is probably开发者_如何学Go not thread safe, and this is hapenning due to race conditions.

I would like to know: Is there a way I can fix this other than constantly polling the processing thread for it's progress from the main thread using a timer?

Is using the GUI from any thread other the main one inherently unsafe?

Thanks in advance.

EDIT: I'm following Marc's instructions but there's still something wrong, because my NSAlerts (which I'm also using now) are still disappearing. Here's my processing thread.

- (void)doProcess:(id)param
{
    // ...
    [self performSelectorOnMainThread:@selector(askForConfirmation) withObject:nil waitUntilDone:YES];
    // ...
}

Then on my main thread:

- (void)askForConfirmation
{
    [[NSAlert alertWithMessageText:@"Test." defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"Testing."] runModal];
}

- (IBAction)startProcessing:(id)sender
{
    // ...
    [NSThread detachNewThreadSelector:@selector(doProcess:) toTarget:self withObject:nil];
    // ...
}


The main thread is the GUI thread. You should not do any GUI stuff on any background threads. That being said, you can write a method that calls NSRunAlertPanel() and then call your method by using one of NSObject's performSelectorOnMainThread: methods.

To check if you are currently executing on the main thread, you can just call [NSThread isMainThread].

0

精彩评论

暂无评论...
验证码 换一张
取 消