Несколько запросов с DispatchQueue.main.async не выполняются должным образом в swift 3

У меня есть JSON, через который я получаю список досок. Доступ к нему осуществляется через self.jsonGame.boards. Теперь я должен вызывать все эти платы и отображать содержимое.

Но платы не называются последовательно. Иногда они появляются.

func fetchBoard(){

    let repo = GameRepository()
    let prefs = UserDefaults.standard
    if self.jsonGame.boards.count > 0 {
        self.sortedBoardArr.reserveCapacity(self.BoardArr.count)

        for board in self.jsonGame.boards{

            DispatchQueue.main.async
            {
                    repo.GetBoardInfo(gameID: self.jsonGame.Id, boardID: board ,  completion : {(response , errorCode ) -> Void in

                        if errorCode == ErrorCode.NoError{
                            DispatchQueue.main.sync {

                                self.BoardArr.append(response)
                                self.sortArr()
                                self.collectionView.reloadData()

                            }
                        }

                    })
            }
        }
    }
}

func sortArr(){
    if self.jsonGame.boards.count == self.BoardArr.count{
        for board in self.jsonGame.boards{
            for boardarr in self.BoardArr{
                if boardarr.id == board{
                    self.sortedBoardArr.append(boardarr)
                }
            }
        }
    }
}

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

Я noob при асинхронной обработке. Извините за беспокойство.

+1
источник поделиться
1 ответ

У меня была аналогичная проблема, когда я заполнил массив элементами, исходящими из разных асинхронных сетевых запросов, и когда запросы выполнялись одновременно, конечный размер моего массива зависел от выполнения параллельных задач.

Мне удалось решить мою проблему с помощью последовательной очереди и групп отправки. Вот как я изменил бы ваш код:

func fetchBoard(){

    let repo = GameRepository()
    let prefs = UserDefaults.standard
    if self.jsonGame.boards.count > 0 {
        self.sortedBoardArr.reserveCapacity(self.BoardArr.count)
        let serialQueue = DispatchQueue(label: "serialQueue")
        let group = DispatchGroup() 
        for board in self.jsonGame.boards{
             group.enter()
             serialQueue.async {
                repo.GetBoardInfo(gameID: self.jsonGame.Id, boardID: board ,  completion : {(response , errorCode ) -> Void in
                    if errorCode == ErrorCode.NoError{
                        self.BoardArr.append(response)
                    }
                    group.leave()
                })
                DispatchQueue.main.async{
                    group.wait()
                    self.sortArr()
                    self.collectionView.reloadData()
                }
            }
        }
    }
}

Эти два ответа на подобные вопросы здесь по переполнению стека были весьма полезны для меня, когда у меня была аналогичная проблема: блокировка асинхронных запросов и параллельных и последовательных очередей

+3
источник

Посмотрите другие вопросы по меткам или Задайте вопрос