正如Martin在评论中所说,计时器的分辨率为50-100毫秒(0.05至0.1秒)。尝试以短于该间隔的时间运行计时器将无法获得可靠的结果。另外,计时器不是实时的。它们取决于它们所附加的运行循环,并且如果运行循环变得繁忙,则计时器的启动会延迟。
不要在每次触发计时器时尝试增加计数器,而是在启动计时器时记录开始时间,然后做一些数学运算以弄清楚发生了多少时间:
var startTime: NSTimeInterval
//Sart the timer
startTime = NSDate.timeIntervalSinceReferenceDate()
NSTimer.scheduledTimerWithTimeInterval(0.02,
target: self,
selector: Selector("advanceTimer:"),
userInfo: nil,
repeats: true)
//And your timer method...
func advanceTimer(timer: NSTimer)
{
//Total time since timer started, in seconds
self.time = NSDate.timeIntervalSinceReferenceDate() - startTime
//The rest of your code goes here
}
此代码的Swift 3版本如下所示:
(写为测试项目中的视图控制器)
class ViewController: UIViewController {
weak var timer: Timer?
var startTime: Double = 0
var time: Double = 0
@IBOutlet weak var timeValueLabel: UILabel!
/*
When the view controller first appears, record the time and start a timer
*/
override func viewDidAppear(_ animated: Bool) {
startTime = Date().timeIntervalSinceReferenceDate
timer = Timer.scheduledTimer(timeInterval: 0.05,
target: self,
selector: #selector(advanceTimer(timer:)),
userInfo: nil,
repeats: true)
}
//When the view controller is about to disappear, invalidate the timer
override func viewWillDisappear(_ animated: Bool) {
timer?.invalidate()
}
func advanceTimer(timer: Timer) {
//Total time since timer started, in seconds
time = Date().timeIntervalSinceReferenceDate - startTime
//The rest of your code goes here
//Convert the time to a string with 2 decimal places
let timeString = String(format: "%.2f", time)
//Display the time string to a label in our view controller
timeValueLabel.text = timeString
}
}