Запуск графического интерфейса Какао в неосновном потоке
У меня возникла проблема с GUI / Threading при разработке пользовательского интерфейса какао. Приложение разработано так:
Основной поток (#1): анализирует аргументы, загружает плагины и т. Д.
Поток графического интерфейса (#?): Запускает графический интерфейс, обрабатывает события и т. Д. Это поток графического интерфейса.
Каркас Какао не является потокобезопасным, но применяет одно правило: графический интерфейс должен выполняться в основном потоке. Утверждение используется, чтобы проверить это. Чтобы попытаться обойти это, я сам реализовал метод run (код ниже), следуя этому - http://cocoawithlove.com/2009/01/demystifying-nsapplication-by.html - руководству. Но я что-то упустил. Окно открывается, но остается пустым (полностью белым). Хотя, если я сделаю звонок в главном потоке, он отлично работает.
В общем, мне нужно выяснить, чего не хватает.
- (void)run
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[self finishLaunching];
shouldKeepRunning = YES;
do
{
[pool release];
pool = [[NSAutoreleasePool alloc] init];
NSEvent *event =
[self
nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate distantFuture]
inMode:NSDefaultRunLoopMode
dequeue:YES];
[self sendEvent:event];
[self updateWindows];
} while (shouldKeepRunning);
[pool release];
}
- (void)terminate:(id)sender
{
shouldKeepRunning = NO;
}
3 ответа
Не. Этот подход никогда не сработает. Даже если вы исправите свою текущую проблему (окно не рисует), вы сразу же столкнетесь с другой неясной проблемой, которую невозможно исправить, и другой, и другой. Какао ожидает, что поток GUI будет основным, конец истории.
Делайте все в фоновом потоке, кроме обновления GUI. Я вижу, что у вас есть только строка, где вам нужно обновить графический интерфейс. Так что делайте так, как вы делаете, за исключением того, что вы выполняете все обновления GUI в основном потоке:
dispatch_async(dispatch_get_main_queue(), ^
{
[self updateWindows];
});
Теперь я не знаю, что такое updateWindows, я предположил, что это не создаст условия гонки.
Почему бы не решить проблему? Сделайте так, чтобы основной поток порождал поток (назовем это потоком приложения), а затем блокировал перед созданием графического интерфейса. Поток приложения будет анализировать аргументы, загружать плагины и т. Д. После завершения инициализации поток приложения будет сигнализировать основному потоку о необходимости запуска и запуске графического интерфейса.