NSRunAlertPanel()主线程之外?

时间:2009-10-07 21:47:01

标签: objective-c cocoa multithreading

我偶然发现了我正在使用cocoa开发的应用程序中的一个问题。 我需要做一些处理,我在一个单独的线程上做。我这样做,所以我可以使用NSProgressIndicator显示进度,而不是挂起主线程。 (如果用户愿意,用户可以取消执行。)

它几乎完美无缺,但是有一个问题:处理会产生大量文件,如果这些文件中有一个或多个已经存在,我想问用户是否可以在实际操作之前覆盖它们。所以我尝试使用处理线程中的NSRunAlertPanel()。

有些时候有效。其他时候,警报面板会闪烁,在我点击之前没有特殊原因关闭,或根本不显示。所以我认为NSRunAlertPanel()可能不是线程安全的,而且由于竞争条件的原因,这种情况很糟糕。

我想知道:除了不断地使用计时器从主线程轮询处理线程的进度之外,有没有办法可以解决这个问题?

是否使用其他线程的GUI,其中主要的一个本身就不安全?

提前致谢。

编辑:我正在遵循Marc的指示,但仍然有问题,因为我的NSAlerts(我现在也在使用)仍在消失。这是我的处理线程。

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

然后在我的主线上:

- (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];
    // ...
}

1 个答案:

答案 0 :(得分:4)

主线程是GUI线程。你不应该在任何后台线程上做任何GUI的东西。话虽如此,您可以编写一个调用NSRunAlertPanel()的方法,然后使用NSObject的{​​{1}}方法之一调用您的方法。

要检查您当前是否正在主线程上执行,您只需拨打performSelectorOnMainThread: