使用多个DispatchQueue.main.async查看冻结 [英] View Freezes with multiple DispatchQueue.main.async use

查看:170
本文介绍了使用多个DispatchQueue.main.async查看冻结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

查看冻结,同时获取并显示数据.根据我的理解,fetchBoard()initUserInfo()不会并行执行. (因为视图仅在fetchBoard()加载电路板时加载) 我担心是否多次使用DispatchQueue.main.async会冻结视图.另外,如何使它顺利运行.

View Freezes while data is fetched and displayed. In my understanding fetchBoard() and initUserInfo() do not execute in parallel. (As view only loads when fetchBoard() loads the boards) I'm concerned if the use of DispatchQueue.main.async multiple times is freezing the view. Also, How do I make it work smoothly.

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
}

}

寻找顺畅的工作,而不是冻结视图.我不是在处理Dispatch.欢迎任何帮助.预先感谢.

Looking for the smooth working and not freezing the view. I'm noob at working with Dispatch. Any help is welcome. Thanks in advance.

推荐答案

使用notify()而不是wait()不会阻塞主线程.

Use notify() instead of wait() to not block the main thread.

操场上的例子:

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!


在此答案中找到的其他原因.


Additional Info why you are causing a deadlock can be found in this answer.

这篇关于使用多个DispatchQueue.main.async查看冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆