iOS Timer未终止问题求助:定时调用API后定时器无法停止
解决Timer无法停止及重复弹窗问题
我看了你的代码,发现几个核心问题导致Timer失控,咱们一步步来修复:
主要问题分析
- 变量名不匹配:你定义的Timer是
myTimer,但在停止Timer时操作的却是acceptOrRejectTimer——这两个不是同一个对象,自然停不了原来的Timer。 - 90秒延迟逻辑错误:每次调用
COStatusAPI都会新建一个90秒后的异步任务,导致如果连续调用多次API,会有多个弹窗任务在后台等待,就算提前触发了COStatus=1,这些旧任务还是会执行。 - Timer重复参数设置错误:创建Timer时用
timeController作为repeats参数,这会导致Timer可能在一开始就不重复,而且后续修改timeController也不会影响已经创建的Timer(因为repeats是创建时的一次性参数)。
修复后的代码
var myTimer: Timer? var startTime: Date? // 记录Timer开始运行的时间 func myAPICall() { self.loadingview() // 确保Timer只创建一次 if myTimer == nil { startTime = Date() myTimer = Timer.scheduledTimer( timeInterval: 5.0, target: self, selector: #selector(COStatusAPI), userInfo: nil, repeats: true // 固定设为true,直到手动停止 ) } } @objc func COStatusAPI() { // 先检查是否已经超时(超过90秒) guard let startTime = startTime else { return } let elapsedTime = Date().timeIntervalSince(startTime) if elapsedTime >= 90 { stopTimer() self.hideloadingview() // 弹出超时提示框 return } if COStatus == 1 { stopTimer() self.hideloadingview() // 跳转到下一个ViewController } else if COStatus == 0 { // 继续循环,什么都不用做,Timer会自动在5秒后再次调用 } } // 封装停止Timer的方法,避免重复代码 private func stopTimer() { myTimer?.invalidate() myTimer = nil startTime = nil // 清空开始时间 }
关键修改说明
- 统一Timer变量:全程使用
myTimer,并封装stopTimer()方法,确保停止逻辑一致,避免重复代码。 - 用时间差判断超时:记录Timer启动的
startTime,每次调用API时计算已运行时间,超过90秒就停止Timer并弹窗——这样只会有一次超时判断,不会重复创建异步任务。 - 固定Timer重复参数:创建Timer时
repeats设为true,因为我们需要它持续重复执行,直到手动调用invalidate()停止。 - 提前判断超时:每次调用API先检查是否超时,避免在已经超时的情况下继续处理COStatus逻辑。
这样修改后,无论是COStatus=1触发跳转,还是90秒超时,都能准确停止Timer,不会出现后台残留任务导致的重复弹窗问题。
内容的提问来源于stack exchange,提问作者Bhanuteja
相关产品推荐
相关产品推荐

