Когда я обновляю свой пользовательский интерфейс в ответ на асинхронное действие, где я должен вызвать DispatchQueue?

В моем приложении для iOS я делаю много веб-запросов. Когда эти запросы выполняются / не выполняются, запускается метод делегата в контроллере представления. Метод делегата содержит код, который отвечает за обновление пользовательского интерфейса. В следующих примерах didUpdate(foo:) это метод делегата, и presentAlert(text:) мое обновление пользовательского интерфейса.

Без DispatchQueueкод хотел бы это:

func didUpdate(foo: Foo) {
  self.presentAlert(text: foo.text)
}

func presentAlert(text: String) {
  let alertController = ...

  self.present(alertController, animated: true)
}

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

Первый путь:

func didUpdate(foo: Foo) {
  self.presentAlert(text: foo.text)
}

func presentAlert(text: String) {
  let alertController = ...

  DispatchQueue.main.async {
    self.present(alertController, animated: true)
  }
}

Второй способ:

func didUpdate(foo: Foo) {
  DispatchQueue.main.async {
    self.presentAlert(text: foo.text)
  }
}

func presentAlert(text: String) {
  let alertController = ...

  self.present(alertController, animated: true)
}
  • Имеет ли значение, с каким подходом я иду? Кажется, что наличие блока DispatchQueue внутри presentAlert функция лучше, поэтому мне не нужно включать DispatchQueue.main.async в любое время я хочу позвонить presentAlert?

  • Нужно ли явно отправлять блок в основную очередь, когда вы (или используемая вами среда) "переместились" в фоновую очередь?

  • Если есть какие-либо внешние ресурсы, которые могут помочь моему пониманию GCD, пожалуйста, дайте мне знать!

1 ответ

Решение

Имеет ли значение, с каким подходом я иду? Кажется, что лучше иметь блок DispatchQueue внутри функции presentAlert, поэтому мне не нужно включать DispatchQueue.main.async всякий раз, когда я хочу вызвать presentAlert?

Нет разницы между двумя подходами. Но недостаток второго подхода, как вы сказали, заключается в том, что вы должны обернуть все presentAlert вокруг DispatchQueue.main.async закрытие.

Нужно ли явно отправлять блок в основную очередь, когда вы (или используемая вами среда) "переместились" в фоновую очередь?

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

Если есть какие-либо внешние ресурсы, которые могут помочь моему пониманию GCD, пожалуйста, дайте мне знать!

В Интернете есть много источников, чтобы лучше понять GCD. Проверьте это руководство Raywenderlich. Это хорошее место для начала.

Я рекомендую, если у вас есть центральный класс, который обрабатывает все вызовы веб-службы, может быть лучше вызвать закрытие обратного вызова завершения в главной очереди, когда вы проанализируете свои данные после получения ответа веб-службы. Таким образом, вам не нужно будет отправлять сообщения в основную очередь в ваших представлениях или классах viewcontroller.

Другие вопросы по тегам