Приводит ли вызов dispatch_sync(dispatch_get_global_queue()) в основном потоке к зависанию приложения?

// Method called when a button is clicked

- (void)handleClickEvent {
      dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
         [self backgroundProcessing];
      });
      // Some code to update the UI of the view
      ....
      [self updateUI];
      ....
}

1) handleClickEvent вызывается в основном потоке при нажатии кнопки в представлении.

2) Я использовал dispatch_sync(), потому что следующий код, который обновляет пользовательский интерфейс представления, не может быть выполнен до тех пор, пока не будет вычислена переменная в методе backgroundProcessing.

3) Я использовал dispatch_get_global_queue, чтобы отключить фоновую обработку от основного потока. (следуя правилу: обычно отключайте фоновую обработку от основного потока и обычно помещайте код, влияющий на пользовательский интерфейс, в основной поток).

Мой вопрос: метод backgroundProcessing «подвешивает» основной поток до его завершения, так как я использую dispatch_sync?

EDIT: На основе приведенного ниже ответа я реализовал это решение:

- (void)handleClickEvent {
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
         [self backgroundProcessing];
         dispatch_async(dispatch_get_main_queue(), ^{
            [self updateUI];
         });
      });
}

решение по этой ссылке: Вызовы завершения< /а>


person Just a coder    schedule 09.01.2012    source источник


Ответы (1)


Да, dispatch_sync будет блокироваться до тех пор, пока задача не будет завершена. Используйте dispatch_async, и когда задание будет завершено, отправьте блок обратно в основную очередь, чтобы обновить представление.

person Gary    schedule 09.01.2012
comment
Хорошо, поэтому он заблокирует основной поток, даже если он был отправлен в глобальную очередь. Понял тебя. Хорошо, большое спасибо. Я отредактировал вопрос выше, чтобы показать ответ, который я реализовал. - person Just a coder; 09.01.2012
comment
Я думаю, ключевая строка из документации по dispatch_sync(), которую вы, возможно, пропустили, была следующей: в качестве оптимизации, dispatch_sync() вызывает блок в текущем потоке, когда это возможно. Чтобы достичь желаемого эффекта, вы должны были асинхронно отправить работу, а затем асинхронно отправить обновление пользовательского интерфейса в основную очередь, когда работа будет выполнена. Это распространенный шаблон. - person jkh; 10.01.2012