使用多个DispatchQueue.main.async查看冻结 [英] View Freezes with multiple DispatchQueue.main.async use
问题描述
查看冻结,同时获取并显示数据.根据我的理解,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屋!