Swift NSTiimer没有遵循指定的间隔

我正在尝试创建一个测验应用程序,该应用程序在计时器到期时(即10秒,并且我希望Timer的间隔为1秒)为每个问题提供一个计时器,它会自行重置并提取下一个问题,然后再次计时器从10重新开始...但是我的问题是,当第一个问题被加载时,计时器没有遵循固定的时间间隔,它显示的间隔为2 ...即10,8,6 ..然后对于第二个问题,它使跳转为3秒间隔,并且间隔类似地增加。

导入UIKit

class ViewController: UIViewController {

    let allQuestions = QuestionsBundle()
    var pickedAnswer : Int = 0
    var questionCounter = 0
    var score : Int = 0
    var timer: Timer!
    
    
    
    
    @IBOutlet weak var questionLabel: UILabel!
    @IBOutlet weak var countDownLabel: UILabel!
    
    @IBOutlet weak var ansLbl1: UILabel!
    @IBOutlet weak var ansLbl2: UILabel!
    @IBOutlet weak var ansLbl3: UILabel!
    @IBOutlet weak var ansLbl4: UILabel!
    
    
    
    @IBOutlet weak var checkBox1: CheckBox!
    @IBOutlet weak var checkBox2: CheckBox!
    @IBOutlet weak var checkBox3: CheckBox!
    @IBOutlet weak var checkBox4: CheckBox!
    
    var checkBoxlist : [CheckBox] = []
 
    
    @IBaction func correct_Answer_Checbox_Btn(_ sender: AnyObject) {
        //print("\(sender.tag) <==> \(String(describing: question?.correctAnswer))")
        
        updateCheckBoxes(sender: sender)
        
        if sender.tag == question?.correctAnswer{
           question?.isAnswerCorrect = true
            question?.selectedAnswer = sender.tag
            //score = score + 1
            
            
        }
            
        else {
            question?.isAnswerCorrect = false
        }
        
    }
    
    func updateCheckBoxes(sender: AnyObject){
        for checkBoxItem in checkBoxlist{
            if checkBoxItem.tag != sender.tag {
                checkBoxItem.isChecked = false
            }
        }
        
    }
    
    @IBOutlet weak var nextButton: UIButton!
    @IBaction func nextBtnClicked(_ sender: AnyObject) {
        do{
            try handleNextQuestion()
        }
        catch{
               moveToResultView()
        }
       
        
    }
    
    func handleNextQuestion() throws {
        nextQuestion()
        if questionCounter == allQuestions.list.count-1{
            finishButton.isHidden = false
            nextButton.isHidden = true
            //scoreLbl.text = "\(score)"
        }
    }
    
    var question : Question?
    
    var countTime = 10.0
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        finishButton?.isHidden = true
        checkBoxlist = fetchCheckBoxList()
        question = fetchQuestion()
        setQuizView(question: question!)
        
        
        // Do any additional setup after loading the view,typically from a nib.
    }
    
    
  
    
    // set all questions in a function
    
    @objc func update() {
        if(countTime > 0) {
            countTime = countTime - 1
            self.countDownLabel.text = String(countTime)
        }else{
            timer.invalidate()
            countTime = 10.0
            do{

                try handleNextQuestion()

            }
            catch{
                   moveToResultView()
            }
            
        }
    }
 
    
   
    func startTimer() {
        timer = Timer.scheduledTimer(timeInterval: 1.0,target: self,selector: #selector(ViewController.update),userInfo: nil,repeats: true)
    }
    func setQuizView(question:Question)  {
        self.countDownLabel.text = "10"
        
        startTimer()
        questionLabel.text =  question.questionText
        ansLbl1.text =  question.answer1
        ansLbl2.text =  question.answer2
        ansLbl3.text =  question.answer3
        ansLbl4.text =  question.answer4
        
        if question.selectedAnswer == Constants.DEFAULT_ANSWER {
            for checkBoxItem in checkBoxlist{
                checkBoxItem.isChecked = false
            }
            
        }
        
    }
    
    
    @IBOutlet weak var finishButton: UIButton!
    
    // prepare segue
    override func prepare(for segue: uistoryboardSegue,sender: Any?) {
        
            if segue.identifier == resultScreenIdentifier{
            let vc = segue.destination as! ResultViewController
            vc.data = sender as! String
            
        }
    }
    
    let resultScreenIdentifier = "resultScreenSegue"
    
    func moveToResultView(){
         performSegue(withIdentifier: resultScreenIdentifier,sender: score)
    }
    
    @IBaction func finishButtonClicked(_ sender: UIButton) {
        
        //perform segue
        let score = "\(calculateScore())"
        moveToResultView()
        
    }
    // calculate the score of quiz using loop
    func calculateScore()->Int{
        var numOfCorrectAnswers = 0
        for question in allQuestions.list{
            if question.isAnswerCorrect {
                numOfCorrectAnswers = numOfCorrectAnswers + 1
                //print(numOfCorrectAnswers)
            }
        }
        return numOfCorrectAnswers
    }
    func nextQuestion(){
        showResultView(isCorrect: (question?.isAnswerCorrect)!)
        questionCounter = questionCounter + 1
        question = fetchQuestion()
        setQuizView(question: question!)
        
        
    }
    
    func fetchQuestion() ->  Question{
       return  allQuestions.list[questionCounter]
    }
    

    func fetchCheckBoxList() -> [CheckBox]{
        let arr : [CheckBox] = [checkBox1,checkBox2,checkBox3,checkBox4]
        return arr
    }

}
eventuallyfantasy 回答:Swift NSTiimer没有遵循指定的间隔

Timer并不是特别准确。他们会遭受明显的抖动。

一种更好的方法是创建一个表示到期时间的Date(即Date(timeIntervalSinceNow:10),然后以更短的间隔运行Timer(我建议大约0.1秒)。然后,您可以根据目标Date计算剩余时间,并检查目标日期是否过去。

本文链接:https://www.f2er.com/1470468.html

大家都在问