我偶然发现了我正在使用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];
// ...
}
答案 0 :(得分:4)
主线程是GUI线程。你不应该在任何后台线程上做任何GUI的东西。话虽如此,您可以编写一个调用NSRunAlertPanel()
的方法,然后使用NSObject
的{{1}}方法之一调用您的方法。
要检查您当前是否正在主线程上执行,您只需拨打performSelectorOnMainThread:
。