Swift Xcode中为循环添加时间延迟实现经营游戏定时增长收益
问题核心原因
你现在的写法存在三个核心问题:
- 把无限死循环写在了按钮点击事件中,同时使用了
sleep()函数,二者都会直接阻塞iOS的UI主线程,执行到这段代码时整个APP的交互、界面刷新都会完全卡住,完全无法实现定时增值的效果 - 现金增值逻辑错误,你用的是赋值语句
cashTotal = 5 * applemultiplier,会直接覆盖原有现金总额,应该用累加逻辑才符合经营游戏的收益规则 - 存在业务逻辑bug:买苹果时扣除的是番茄的总价
tomatoTotal,应该扣除苹果的售价appletotal才符合预期
正确实现方案
iOS端做定时重复任务应该使用Timer类,你可以选择在用户首次购买资产时启动定时器,也可以选择进入页面就启动定时器,修改后的完整可运行代码如下:
import UIKit class ViewController: UIViewController { @IBOutlet weak var cash: UILabel! @IBOutlet weak var applePrice: UILabel! @IBOutlet weak var tomatoPrice: UILabel! @IBOutlet weak var berryPrice: UILabel! var cashTotal = 100 var appletotal = 5 var berrytotal = 10 var tomatoTotal = 15 var applemultiplier = 1 // 声明定时器全局变量 var incomeTimer: Timer? override func viewDidLoad() { super.viewDidLoad() // 进入页面初始化所有UI显示 refreshAllUI() // 如果需要启动APP就开始计算收益,可以在这里直接调用启动定时器的方法 // startIncomeTimer() } // 统一刷新UI的公共方法,避免重复写UI更新代码 func refreshAllUI() { cash.text = "Cash: \(cashTotal)" applePrice.text = "Price: \(appletotal)" // 后续番茄、蓝莓的UI更新逻辑也可以统一加在这里 } // 启动收益定时器的方法 func startIncomeTimer() { // 避免重复创建多个定时器 guard incomeTimer == nil else { return } // 每20秒触发一次收益计算,可根据需求调整时间间隔 incomeTimer = Timer.scheduledTimer(withTimeInterval: 20, repeats: true, block: { [weak self] _ in guard let self = self else { return } // 累加苹果的收益,后续新增其他资产收益只需要在这里加对应计算逻辑即可 self.cashTotal += 5 * self.applemultiplier // 刷新现金显示 self.refreshAllUI() }) } @IBAction func buyapple(_ sender: Any) { if cashTotal >= appletotal { // 修正扣钱逻辑,扣除对应苹果的售价 cashTotal -= appletotal applemultiplier += 1 appletotal *= applemultiplier refreshAllUI() // 首次购买苹果时启动收益定时器 startIncomeTimer() } } @IBAction func buyberry(_ sender: Any) { // 后续蓝莓的购买、收益逻辑和苹果逻辑一致 } @IBAction func buytomato(_ sender: Any) { // 后续番茄的购买、收益逻辑和苹果逻辑一致 } // 页面销毁时停止定时器,避免内存泄漏 deinit { incomeTimer?.invalidate() incomeTimer = nil } }
额外说明
Timer的定时存在毫秒级的微小误差,完全满足休闲经营类游戏的精度要求,如果需要更高精度的收益计算,可以存储收益开始的时间戳,每次定时器触发时用时间差计算总收益即可- 所有UI更新逻辑必须在主线程执行,上述
Timer的写法默认触发在主线程,不需要额外做线程切换处理
内容的提问来源于stack exchange,提问作者niquidx
相关产品推荐
相关产品推荐

