2013-07-18 110 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