2013-07-18 73 views
0

偶尔我必须在我的Cocoa代码段中做一个弹出式警报窗口。以前我直接使用NSAlert然后有runModal去,而我发现NSRunAlertPanel更容易实现我的目标。所以我决定将我所有的提醒功能切换到NSRunAlertPanel。在大多数时间似乎没问题。NSRunAlertPanel导致多线程性能问题

现在我正在添加多线程。当在主线程中回拨时,我发现NSRunAlertPanel显然比NSAlert慢。

代码段:

首先,我创建一个线程:

[NSThread detachNewThreadSelector: @selector(tryRunLoop:) toTarget:self withObject:nil]; 

那么这个功能tryRunLoop在这个线程调用警报窗口函数在主线程:

while(1) 
[self performSelectorOnMainThread:@selector(showAlert:) withObject:anObject waitUntilDone:YES]; 

功能showAlert在主线中做其余的事情:

NSRunAlertPanel(@"Warning:",@"Just testing", @"YES", nil, nil); 

随着时间的推移弹出窗口的反应似乎慢,slower.If我用NSAlert代替NSRunAlertPanel,或没有运行在主线程中弹出的方法,症状就会消失。

我还发现这两种方法的CPU使用率也不同。显然NSAlert在按下按钮的同时,CPU使用率很低。

有人能解释这些现象吗?

PS:我没有被允许把整个原创项目放在网上,因此我在Github上创建了一个简单的Cocoa项目来模拟症状和URL,请首先阅读自述文件中的Known issues

+0

这听起来似乎有些疯狂的真正代码。为什么要创建一个新线程来传递给主线程呢? –

+0

@MikeAbdullah如果你想根据Cocoa开发显示Alert窗口,所有的警报消息都必须发送到主线程。并且你的意思是循环中有一个新线程?事实上,我尝试过,但情况似乎是一样的。 – othercat

+0

正确,是的,警报必须在主线程上运行。上面的代码我不明白你为什么要分离一个* new *线程,它显然没有任何东西,只有消息传递到主线程 –

回答

0

好的,简短的回答是不要使用NSRunAlertPanel。这一系列职能已经被阻止了一段时间,并被NSAlert所取代。改为使用NSAlert

(不幸的是,NSRunAlertPanel等类引用并没有提到这一点;我试图记住它第一次证明;也许是发行说明)

+1

在[NSAlert]的介绍中有一个注释(https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSAlert_Class/Reference/Reference.html)文档。 – JeremyP