Когда я обновляю свой пользовательский интерфейс в ответ на асинхронное действие, где я должен вызвать 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.