Из того, что я могу сказать, вы используете dispatchGroup неправильно.
Подводя итог notify()
:
- , он запускает связанный блок, когда все текущие в очереди блоки в группезавершены
- блок запускается только один раз, а затем освобождается
- если очередь группы пуста, блок запускается немедленно
Проблема, которую я вижу в том, чтов соответствии с тем, как написан ваш код извлечения, группа думает, что ее очередь пуста, когда вы вызываете notify.Таким образом, блок notify()
запускается немедленно, и тогда вы видите, что ячейки заполняются только тогда, когда они перезагружаются во время прокрутки.
Есть два способа заполнить очередь dispatchGroup:
- вызов
DispatchQueue.async()
и передать группу, чтобы поставить в очередь блок и связать его с группой - , вручную вызвать
enter()
, когда блок начинается, и leave()
, когда он заканчивается, что увеличивает / уменьшает внутренний счетчик наgroup
Первый способ безопаснее, так как вам не нужно отслеживать блоки самостоятельно, а второй более гибок, если у вас нет контроля над очередью блока.например, запустить.
Поскольку вы используете enter/leave
, вам необходимо убедиться, что вы вызываете enter()
для каждого отдельного рабочего элемента (в вашем случае асинхронные вызовы backend
),и звоните leave()
только тогда, когда каждый из этих рабочих элементов завершается.Я не уверен, как вы используете методы делегата, но, кажется, нет одного для каждого вызова backend
, поскольку существует 5 различных вызовов и только 2 метода делегата.Это также не похоже на то, что методы делегата будут вызваны, если в бэкэнд-вызове произошла ошибка.
Я бы рекомендовал изменить вызовы backend
, чтобы использовать вместо них блоки завершения, но если вы хотите придерживатьсяшаблон делегата, вот как вы можете это сделать:
func getData(){
backend.movieDelegate = self
backend.actorDelegate = self
dispatchGroup.enter()
backend.getMoviePopularList()
dispatchGroup.enter()
backend.getMovieTopRatedList()
dispatchGroup.enter()
backend.getMovieUpcomingList()
dispatchGroup.enter()
backend.getPopularActors()
dispatchGroup.enter()
backend.getMovieNowPlayingList()
dispatchGroup.notify(queue: .main) {
SVProgressHUD.dismiss()
self._tableView.isHidden = false
self._tableView.dataSource = self
self._tableView.delegate = self
self._tableView.reloadData()
}
}
func transferPopularMovies(data: [MovieModel]) {
popularMovies = data
dispatchGroup.leave()
}
func transferTopRatedMovies(data: [MovieModel]) {
topRatedMovies = data
dispatchGroup.leave()
}
func transferUpcomingMovies(data: [MovieModel]) {
upcomingMovies = data
dispatchGroup.leave()
}
func transferActors(data: [ActorModel]) {
popularActors = data
dispatchGroup.leave()
}
func transferNowPlayingMovies(data: [MovieModel]) {
nowPlayingMovies = data
dispatchGroup.leave()
}
Не забудьте вызвать методы делегата, даже если есть ошибка, чтобы убедиться, что вызовы enter/leave
сбалансированы.Если вы звоните enter
чаще, чем leave
, блок notify
никогда не запускается.Если вы звоните leave
чаще, вы терпите крах.