我正在尝试使用 swift 在 iOS 中实现一个简单的游戏。游戏为回合制;第一个玩家移动,然后是第二个玩家,然后是第一个…… 我为此使用了一个协议:
class PersonAgent: AgentProtocol {
let agentType: AgentType = .person
let color: UIColor
var points: Int = 0
private var tappedLine: Line?
init(color: UIColor) {
self.color = color
}
func action() async -> Line {
while self.tappedLine == nil {}
guard let tappedLine = self.tappedLine else { fatalError() }
self.tappedLine = nil
return tappedLine
}
func tapped(line: Line) {
self.tappedLine = line
}
}
当用户点击按钮时,视图控制器调用点击的函数,之后,操作方法可以返回一些内容。问题是,对于这样一个简单的游戏来说,手机会变得过热。我可以在不使用 while 的情况下达到相同的功能吗?有什么建议可以提高CPU和内存虎钳的效率吗?
为了让事情更清楚,我在视图控制器中有这段代码:
extension BoardViewController {
private func game() {
print(#function)
Task {
print("inside task")
while self.shouldResumeGame() {
print("Turn Iteration")
var shouldChangeTurn = true
let currentAgent: AgentProtocol
switch self.turn {
case .first:
currentAgent = self.firstAgent
case .second:
currentAgent = self.secondAgent
}
let actionResult = await currentAgent.action()
// some logic here
}
let message: String
if self.firstAgent.points > self.secondAgent.points {
message = "First Player Won"
} else if self.firstAgent.points < self.secondAgent.points {
message = "Second Player Won"
} else {
message = "Draw"
}
// MARK: Game finished
let alert = UIAlertController(title: "Game Finished", message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: { [weak self] _ in
self?.navigationController?.popViewController(animated: true)
}))
self.present(alert, animated: true)
}
}
private func shouldResumeGame() -> Bool {
return self.firstAgent.points + self.secondAgent.points != 60
}
}
不要使用
while
循环。这是投票
现代应用程序使用事件驱动的方法,其中用户交互或计时器触发等事件会触发操作。
例如,
while self.tappedLine == nil {}
将执行每秒数百万次。
您没有提供足够的信息让我给您一个完整的答案,但是重构
PersonAgent
的一种方法是使用 CheckedContinuation
:
class PersonAgent:AgentProtocol {
let agentType: AgentType = .person
let color: UIColor
var points: Int = 0
var continuation: CheckedContinuation<Line,Never>?
init(color: UIColor) {
self.color = color
}
func action() async -> Line {
guard self.continuation == nil else {
fatalError("Action called while already awaiting")
}
let tappedLine = await withCheckedContinuation { continuation in
self.continuation=continuation
}
self.continuation = nil
return tappedLine
}
func tapped(line: Line) {
self.continuation?.resume(returning:line)
}
}
现在该线路没有轮询。
action
函数创建一个延续并等待它被恢复。 tapped
函数恢复所点击的线的延续。