multithreading - 如何强制在 Swift 中更新 UI?
问题描述
我正在使用 swift 开发国际象棋游戏。当计算机自己玩时,移动完成后显示不会更新,直到它退出循环(在这种情况下游戏结束)。
我试图在后台队列中调度它以生成移动并将其调度回主队列以进行移动并更新显示。虽然这似乎有助于更新显示,但我无法预测每个后台队列的完成情况。这打乱了动作的顺序。
有没有更好的方法让电脑自动播放并在每次移动完成后正确更新显示?
while chessGame.checkmate != true {
DispatchQueue.global(qos: .background).async {
let bestMove = chessAI.findBestMove(depth : chessGame.searchDepth)
if bestMove != nil {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()) {
chessMove.makeMove(m : bestMove!)
self.boardView.setNeedsDisplay()
}
} else {
print("CheckMate!")
chessGame.checkmate = true
}
}
}
解决方案
您可以立即强制显示(通过调用displayIfNeeded
),但这无济于事。
问题是while
循环不会在迭代之间暂停:它只是保持以最高速度循环。因此,while
循环是一个糟糕的策略。
相反,使用递归。这使您可以控制何时进行下一次迭代,即延迟后递归。这是一个循环,您可以在迭代之间暂停。
伪代码:
func nextMove() {
DispatchQueue.global(qos: .background).async {
let bestMove = chessAI.findBestMove(depth : chessGame.searchDepth)
if bestMove != nil {
DispatchQueue.main.asyncAfter(deadline: .now() + 3) { // or whatever
chessMove.makeMove(m : bestMove!)
self.boardView.setNeedsDisplay()
if chessGame.checkmate != true {
nextMove()
} else {
print("checkmate")
}
}
}
}
}
推荐阅读
- java - 使用 JUnit 在注解中创建注解
- android - 接口在 MVVM 中是否仍然相关?
- bash - Bash:防止在嵌套函数上声明的变量的覆盖隐私
- javascript - 更改日期输入格式 PHP/Bootstrap/Javascript/HTML5
- java - Maven - 带有 Java 10 的 javax.annotation
- wordpress - WordPress插件功能
- css - 实现次要内容不会正确垂直对齐
- python - 是否可以在 Keras 中实现最大池化层,以提供给定池大小的最大 n 值?
- c# - Moq 可以模拟行为以使用表达式方法参数吗?
- wordpress - WP用户头像前端更新头像