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/