Иногда мне приходится делать всплывающее окно предупреждения в моих сегментах кода какао. Раньше я использовал 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
, или не запускать метод всплывающую в основном потоке, симптом должен исчезнуть.
Я также обнаружил, что использование ЦП также различалось между этими двумя методами. Очевидно, что NSAlert
требует низких затрат на использование ЦП при одновременном нажатии кнопки.
Может ли кто-нибудь объяснить эти феномены?
PS: Я не разрешил поставить весь первоначальный проект в Интернете, так что я создал простое какао проект в Github для имитации симптома и URL, пожалуйста, посмотри на Known issues
в Readme файл в первом.
Это звучит как-то по-настоящему безумный код. Зачем раскручивать свежий поток только для того, чтобы передать сообщение в основной поток? –
@MikeAbdullah Все предупреждающие сообщения должны быть отправлены в основной поток, если вы хотите отображать окна предупреждений в соответствии с разработкой Cocoa. И вы имеете в виду свежий поток в цикле? На самом деле я попробовал, но ситуация, похоже, та же. – othercat
Правильно, да, предупреждения должны выполняться в основном потоке. То, что я не понимаю из вашего вышеприведенного кода, - это то, почему вы также отключаете поток * new *, который, по-видимому, ничего не делает, кроме сообщения в основной поток. –