【问题标题】:How can I force UI updated in Swift?如何强制在 Swift 中更新 UI?
【发布时间】:2019-10-13 12:24:05
【问题描述】:

我正在使用 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
        }
    }
}

【问题讨论】:

    标签: multithreading user-interface swift3 thread-safety dispatch


    【解决方案1】:

    可以立即强制显示(通过调用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")
                    }
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-16
      • 1970-01-01
      • 2018-09-16
      • 2010-11-24
      相关资源
      最近更新 更多