定时器被触发两次并且没有被填充

时间:2017-08-08 20:09:20

标签: ios swift multithreading timer nstimer

我正在遵循this回答中提出的建议。我的计时器有时 nil

func recreateTimer(){

        let timerLog = OSLog(subsystem: "LocationLogger", category: "Timer")

        guard shouldUseTimer == true else {
            os_log("we are using CoreMotion, no need to set timer", log: timerLog, type: .error) 
            return
        }
        if dwellingTimer != nil{

            dwellingTimer?.invalidate()
            dwellingTimer = nil
        }

        lastDwelling = lastLocation

        os_log("Moved more than 160 | invalidated previous timer began new timer", log: timerLog, type: .error)

        DispatchQueue.main.async { [weak self] in

            guard self?.dwellingTimer == nil else{
                os_log("Timer was not niled!!!", log: timerLog, type: .error)
                return
            }
            self?.dwellingTimer = Timer.scheduledTimer(withTimeInterval: 60, repeats: false, block: { timer in
                os_log("we reached 1 minute of no movement",log: timerLog, type: .fault)
                self?.locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
                self?.beginMotionTracking()
                os_log("Timer is deallocated & invalidated | Accuracy: %{public}f | RemainingTime: %{public}f",log: timerLog, type: .fault,(self?.locationManager.desiredAccuracy)!, UIApplication.shared.remainingTime())
            })
        }
        os_log("New Timer is 'likely' set now", log: timerLog, type: .error)
    }

有时我会点击

os_log("we are using CoreMotion, no need to set timer", log: timerLog, type: .error).

1 个答案:

答案 0 :(得分:0)

感谢电磁阀和Paulw11评论,我了解到所有与定时器相关的执行都应该以串行方式完成。

另见invalidate

  

您必须从计时器所在的线程发送此消息   安装即可。如果您从另一个线程发送此消息,则输入   与计时器关联的源可能无法从其运行循环中删除,   这可能会阻止线程正常退出。

除了invalidatingnilling之外(你不想给非nil一个不再传达任何含义的对象),请确保你:

  1. 使用相同的帖子
  2. 您使用的主题是串行
  3. 取决于您对计时器进行更改的位置,您可能需要也可能不需要同步。