View 在获取 数据并显示 时卡住 。在我的理解中 fetchBoard()initUserInfo() 不是并行执行的。 (因为 View 仅在 fetchBoard() 加载板时加载)
我担心多次使用 DispatchQueue.main.async 是否会卡住 View 。另外,我如何让它顺利工作。

class MultipleCardsController2vs2: BaseController, UICollectionViewDataSource , UICollectionViewDelegate {

override func viewDidLoad() {
    super.viewDidLoad()

    let repo = GameRepository()
    repo.CreateGame(gameID : self.jsonGame.Id , completion: { (jsonGame, err) -> Void in
        if(err == ErrorCode.NoError){
            DispatchQueue.main.async{
                self.jsonGame = jsonGame
            }
        }
    })

    //These are the two functions I want these 2 to work in parallel

    self.fetchBoard()           //Function 1
    self.initUserInfo()         //Function 2


    collectionView.delegate = self
    collectionView.dataSource = self


} // .viewDidLoad


func fetchBoard(){

    let repo = GameRepository()
    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{

                //Main async - 1

                group.wait()
                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)
                }
            }
        }
    }

}

fileprivate func initUserInfo()
{
    DispatchQueue.main.async{

                //Main async - 2

            self.name1.text = self.CurrentUser.UserName
            self.imgPlayie1.image = UserManager.GetAvatar(user: self.CurrentUser)
    }
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.jsonGame.boards.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        var cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Round2Cell", for: indexPath) as! Round1vs1cell

        cell.background.backgroundColor = UIColor(white: 1, alpha: 0.0)
        cell = self.populateGameCell(game_res, cell , indexPath)
    return cell
}

fileprivate func populateGameCell(_ game_res: Game_Res, _ cell: Round1vs1cell , _ indexPath : IndexPath ) -> Round1vs1cell
{
    DispatchQueue.main.async {

         //Main async - 3

        cell.background.backgroundColor = UIColor(white: 1, alpha: 0.0)
        cell.word_1.text = game_res.words[0].word
        cell.color_1.image = UIImage(named: "")
        cell.life_1.image =  UIImage(named: "")
        cell.name.text = ""
        cell.op_name.text = game_res.master[index].username
        cell.timeout_left.image = UIImage(named: "Hourglass.png")
        cell.round.text = "Round: \(indexPath.row + 1)"
    }
    return cell
}

}

寻找平稳的工作而不是卡住 View 。我不擅长与 Dispatch 合作。欢迎任何帮助。提前致谢。

最佳答案

使用 notify() 而不是 wait() 来不阻塞主线程。

游乐场示例:

import PlaygroundSupport

func longRunningTask(completion: () -> Void) {
    sleep(1)
    completion()
}

func foo(){
    let queue = DispatchQueue(label: "myQueue")
    let group = DispatchGroup()
    let array = [1, 2, 3]

    for i in array {
        print(i)
        group.enter()
        queue.async {
            longRunningTask {
                print("done \(i)")
                group.leave()
            }
        }
    }

    group.notify(queue: DispatchQueue.main) {
        print("done!")
    }
}

foo()

PlaygroundPage.current.needsIndefiniteExecution = true

打印:
1
2
3
done 1
done 2
done 3
done!

可以在 in this answer 中找到导致死锁的其他信息。

关于ios - 使用多个 DispatchQueue.main.async 来查看卡住,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43871746/

10-14 23:37