使用多个DispatchQueue.main.async查看冻结

时间:2017-05-09 13:51:58

标签: ios swift asynchronous swift3

数据获取并显示时,

查看冻结。在我的理解中initUserInfo()fetchBoard()不要并行执行。 (视图仅在DispatchQueue.main.async加载板时加载) 我担心多次使用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 } } 会冻结视图。另外,我如何使其顺利运作。

{{1}}

寻找顺畅的工作而不是冻结视图。我在与Dispatch合作时很高兴。欢迎任何帮助。提前谢谢。

1 个答案:

答案 0 :(得分:3)

使用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