#swift #async-await #xcode13
Вопрос:
Я загружаю книги из API, показываю индикатор активности при загрузке, обновляю метку после ответа сервера.
activityView.isHidden = false
let task = detach {
do {
let books = try await self.bookService.fetchBooks()
DispatchQueue.main.async {
self.show(books: books)
}
} catch {
DispatchQueue.main.async {
self.resultLabel.text = error.localizedDescription
}
}
DispatchQueue.main.async {
self.activityView.isHidden = true
}
}
//...
Мой вопрос в том, как лучше подходить к обновлению пользовательского интерфейса в основной очереди? DispatchQueue.main.async
выглядят уродливо, и я думаю, что есть лучший подход, чтобы сделать то же самое.
Я должен использовать его, потому что все обновления пользовательского интерфейса должны быть в основном потоке, и я получаю ошибки компилятора без DispatchQueue.main.async
чего-то вроде
Свойство «текст», изолированное от глобального актора «Главный актер», не может быть изменено из неизолированного контекста
или
Свойство «isHidden», изолированное от глобального актора «MainActor», не может быть изменено из неизолированного контекста
P.S. Используйте Xcode 13.0b2
Комментарии:
1.
MainActor.run
Ответ №1:
Используйте @MainActor
вот так —
self.updateAcitivityIndicator(isHidden: false)
let task = detach {
do {
let books = try await self.bookService.fetchBooks()
self.showBooks(books)
} catch {
self.showError(error)
}
self.updateAcitivityIndicator(isHidden: true)
}
@MainActor
private func showBooks(_ books: [Book]) {
}
@MainActor
private func showError(_ error: Error) {
self.resultLabel.text = error.localizedDescription
}
@MainActor
private func updateAcitivityIndicator(isHidden: Bool) {
self.activityView.isHidden = isHidden
}
Комментарии:
1. Эй, Тарун, Что такое
@MainActor
? я ничего об этом не знаю, так что, пожалуйста, скажите мне.2. @jatinfl См.
MainActor
—A singleton actor whose executor is equivalent to the main dispatch queue.
3. поэтому, работая с
@MainActor
нами, нам не нужно играть сGCD
илиOprationQueue
. Верно?4. @jatinflэто разные концепции, которые
@MainActor
были введены сasync
/await
для этой самой цели, которую необходимо решить. Пожалуйста, посмотрите сеансы WWDC 2021 , связанные с параллелизмом Swift, и вы узнаете, что вам нужно.5. Спасибо за объяснение 🙂