2013-03-21 2 views
1

После запуска моей программы я запускаю второй поток, чтобы выполнить некоторую фоновую работу. Эта нить никогда не умрет, но мне нужно дождаться, когда она закончит то, что она делает, прежде чем продолжить основной поток.Ждите флага из фоновой темы

Как заблокировать и возобновить основной поток, пока я жду, пока второй поток обновит его статус?

+0

Вы пробовали что-нибудь или знаете, как это сделать на другом языке? – zneak

+0

У меня было некоторое время() с usleep() в нем, но это не оптимально. Должен быть вызов API, который я могу использовать, чтобы разбудить родительский поток, как только он мне понадобится. – ruipacheco

+4

Runloop, семафор или группа. См. Http://stackoverflow.com/q/818674/412916 – Jano

ответ

8

Во-первых, не блокируйте основную резьбу. Никогда не. Блокировка основного потока достаточно долго на iOS приведет к тому, что ваше приложение будет убито. На OS X это вызовет появление радужной пиццы смерти.

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

Вместо этого попросите приложение выставить модальный диалог или модальный лист или какой-либо другой индикатор состояния, который указывает, что приложение делает что-то, что необходимо сделать до того, как прогресс будет продолжен. Убедитесь, что элемент меню «выйти» все еще включен, если пользователь решает «о, дерьмо! Нет времени для этого! Abort! Abort! Abort!».

Затем, когда ваша фоновая нить завершена, используйте любой из различных механизмов для отправки в основной поток (GCD, performSelector: ... и т. Д.), Что затем приводит к исчезновению «инициализирующей» модальности.

Не нужно опроса, спать или пока() {} вообще.


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

Точно; так, когда он достигает этого состояния, вы можете использовать:

[someObject performSelectorOnMainThread:@selector(sshConnectionEstablished:) withObject:nil]; 

Где someObject может, вероятно, будет ваше приложение делегата.

Или вы могли бы использовать уведомление и сделать что-то вроде:

dispatch_async(dispatch_get_main_queue(), ^{ 
    [[NSNotificationCenter defaultCenter] postNotificationNamed:@"MySSHConnectionEstablished" ....]; 
}); 

Обратите внимания, что хотите ли вы это, чтобы быть асинхронными или синхронизацией до вас.

+0

Мой фоновый поток не был выполнен, он живет более или менее вечно. И мне нужно, чтобы он достиг определенного состояния, прежде чем основной поток сможет это сделать. – ruipacheco

+0

Зачем нужен диспетчер_асинк 'postNotificationNamed'? В любом случае, он не должен немедленно возвращаться. FWIW, если вы google «dispatch_async postNotificationNamed», это единственный результат, который появляется! – Mojo66

+0

@ Mojo66 'postNotificationNamed:' является синхронным, а не асинхронным. Он также отправляет уведомление в поток, на который он был вызван. Итак, если вам нужно обновить интерфейс, вам нужно, чтобы уведомление было опубликовано в основном потоке, и вы обычно делаете это с помощью 'dispatch_async()', или вы рискуете оказаться в тупике. – bbum

Смежные вопросы