Swift - 计时器不会停止

时间:2017-10-06 17:59:34

标签: ios swift timer

我有以下代码:

class firstVC: UIViewController {
    var timer : Timer?

    func scheduledTimerWithTimeInterval(){
        timer = Timer.scheduledTimer(timeInterval: 60, target: self, 
        selector: #selector(self.anotherFunc), userInfo: nil, repeats: 
        true)
    }

    override func viewDidAppear(_ animated: Bool) {
        scheduledTimerWithTimeInterval()
    }
}

我试图阻止计时器但没有成功:

func stopTimer() {
    if timer != nil {
        timer?.invalidate()
        timer = nil
    }
}

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    stopTimer()
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    stopTimer()
}

我甚至尝试将停止功能放在applicationWillResignActive中 在applicationDidEnterBackground但它没有停止:

firstVC().stopTimer()

非常感谢您的帮助。谢谢。

5 个答案:

答案 0 :(得分:7)

正如其他人所说的那样,在开始新的计时器之前,你创建了多个计时器而没有杀死旧计时器。您需要确保在开始新计时器之前停止任何当前计时器。

我所做的是让我的计时器变弱。然后我在尝试创建一个新的计时器之前使用代码`myTimer?.invalidate():

class firstVC: UIViewController {
    weak var timer : Timer?

    func scheduledTimerWithTimeInterval(){
        timer?.invalidate()
        timer = Timer.scheduledTimer(timeInterval: 60, target: self, 
        selector: #selector(self.anotherFunc), userInfo: nil, repeats: 
        true)
    }
}

通过使计时器变弱,唯一能够对计时器保持强引用的是运行循环。然后,当它使它失效时,它会立即释放并设置为nil。通过使用可选链接来调用invalidate方法,如果它已经为nil则不会执行任何操作,并且如果它正在运行则停止它并且导致它变为nil。

请注意,只有使用scheduledTimer()工厂方法之一创建计时器时,此方法才有效。如果您首先尝试创建计时器然后将其添加到运行循环中,则必须使用强大的局部变量来创建它,或者在创建它时立即释放它。

答案 1 :(得分:1)

问题是你的计时器被多次实例化,所以原来的计时器失去了它的引用。 添加变量didStartTimer = false。 然后在viewDidAppear中进行验证,然后调用timer func。 应该这样做。

像这样:

class firstVC: UIViewController {
var timer : Timer?
var didStartTimer = false

func scheduledTimerWithTimeInterval(){
    timer = Timer.scheduledTimer(timeInterval: 60, target: self, 
    selector: #selector(self.anotherFunc), userInfo: nil, repeats: 
    true)
}

override func viewDidAppear(_ animated: Bool) {
            if !didStartTimer {
                 scheduledTimerWithTimeInterval()
                 didStartTime = true
            }

}

答案 2 :(得分:0)

作为调试步骤,请尝试将var timer = Timer()放入全局空间(例如,位于import语句下方的文件顶部),以确保仅创建和引用了一个Timer对象。如果函数中有Timer声明,则每次调用该函数时都会创建一个新计时器,这将导致您失去对旧计时器的引用,并最终不停止使用它。

答案 3 :(得分:0)

经过研究,我找到了解决方案,
对我唯一有效的方法是在AppDelegate文件中创建函数,并在需要时调用它们,
这是timerSwitch函数的代码:

    func timerSwitch()
    {
        if (timerStatus) {
            checkStateTimer = Timer.scheduledTimer(
                timeInterval: 60, 
                target:self, 
                selector: #selector(self.yourFunction), 
                userInfo: nil, repeats: true)
        } else {
            checkStateTimer?.invalidate()
        }
    }

    func stopTimer()
    {
        timerStatus = false
        timerSwitch()

    }

    func startTimer()
    {
        timerStatus = true
        timerSwitch()

    }

“ yourFunction”是您想要在计时器启动时执行的内容,
以我为例发送心跳。
然后我称TimerSwitch是AppDelegate中的以下功能:

    func applicationWillResignActive(_ application: UIApplication) {
        stopTimer()
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        stopTimer() 
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        startTimer()
    }

答案 4 :(得分:-1)

对我没有任何帮助,最后还是用self欺骗了!!

 self.atimer!.invalidate()
 self.atimer = Timer()