Прокачка цикла сообщений Какао из фонового потока - PullRequest
2 голосов
/ 11 января 2012

У меня есть приложение командной строки на основе какао, которое программно создает NSWindow + NSView.Он использует цикл nextEventMatchingMask для ручной накачки цикла событий и отправки событий.Этот цикл периодически вызывается кодом верхнего уровня для опроса входных данных.

Если я запускаю все в главном потоке, это работает нормально, так как представление правильно получает входные события.

Если вместо этогоЯ перемещаю создание окна и цикл обработки сообщений в отдельный поток, затем nextEventMatchingMask больше не возвращает никаких событий, и представление не получает ввод.

Мне известно, что только «основной» поток в приложении Какао должен обрабатывать события.Этот вторичный поток, однако, является единственным потоком, который должен общаться с Какао, поэтому я хотел бы использовать его в качестве "основного" потока, если говорить о Какао.Это возможно?Я вызываю NSApplicationLoad из этого потока, и, насколько я знаю, это первая функция Какао, вызываемая в процессе.

Если я не могу указать, какой из потоков Какао является основным, есть ли другой способ создать NSWindow в фоновом потоке и получать для него события?Я не могу сделать что-то вроде вызова NSApplication Run, потому что я не контролирую основной цикл приложения.Мне просто нужно извлечь входные события из окна, когда код верхнего уровня запрашивает это.

Ответы [ 2 ]

3 голосов
/ 11 января 2012

Может быть, вам нужно запустить runloop во вторичном потоке.В вашем основном потоке, когда вы порождаете свой дополнительный поток, вызывайте что-то вроде этого:

[NSThread detachNewThreadSelector:@selector(launchThread) 
                         toTarget:[ThreadHandler class] 
                       withObject:nil];

В классе ThreadHandler есть что-то вроде:

+ (void)launchThread
{
    NSRunLoop *threadRunLoop = [NSRunLoop currentRunLoop];
    while (someThreadExitCondition && [threadRunLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:1]]);
}

Это должно запустить ваш потоксобытия обработки runloop.Я не уверен, не проверив, позволит ли это вам обрабатывать события для окна, созданного во вторичном потоке, но это может помочь вам понять, как запустить цикл выполнения потока.Вы могли бы даже создать что-то вроде ситуации с распределенными объектами, когда вы прокачиваете события из основного цикла событий через NSConnection во вторичный поток ( пример ).Надеюсь, это, по крайней мере, даст вам другой путь для продолжения.

1 голос
/ 11 января 2012

Я бы не стал полагаться на это поведение.

Если вам нужно запустить бэкэнд в потоке, который не ограничен циклом выполнения, то запустите его во вторичном потоке, чтобы запустить пользовательский интерфейс изосновной поток.

В качестве альтернативы, вы можете создать другой процесс ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...