NSTimer是iOS开发中的定时器机制,常用其ischeduledTimerWithTimeInterval方法来设置定时任务。
我们以一个倒计时的定时器来说明下边几点要注意的事项。
设置定时器
点击按钮,添加一个倒计时的定时器:
func demoNSTimer() {
btn.userInteractionEnabled = !btn.userInteractionEnabled
countdown = countTimer
if (timer != nil) {
timer.invalidate()
timer = nil
}
timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "actionNSTimer", userInfo: nil, repeats: true)
timer.fire()
}
定时器触发:
func actionNSTimer() {
if (countdown < 1) {
if (timer != nil) {
countdown = countTimer
timer.invalidate()
timer = nil
lb.text = "\(countdown)"
lb.alpha = 1.0
}
return;
}
lb.text = "\(countdown)"
lb.transform = CGAffineTransformMakeScale(1.0, 1.0)
lb.alpha = 1.0
countdown = countdown - 1
UIView.animateWithDuration(1.0, animations: { () -> Void in
self.lb.transform = CGAffineTransformMakeScale(2.0, 2.0)
self.lb.alpha = 0.0
}) { (Bool) -> Void in
if (self.countdown == 0) {
self.btn.userInteractionEnabled = true
}
}
}
通过以上代码,可创建一个倒计时的定时器。
暂停和恢复定时器
当定时器正在执行的过程中,暂停是不能使用invalidate方法的,而要重新设置fireDate。
if (timer.valid) {
timer.fireDate = NSDate.distantFuture() // 暂停
// timer.fireData = NSDate.distantPast() // 恢复
}
例如:如果APP进入后台(按下Home键),则一般情况下需要暂停定时器。可在applicationWillResignActive中使用NSNotification来暂停定时器,在applicationDidBecomeActive中再通知恢复定时器。
RunLoop模式
NSTimer不能放在UITableView或UIScrollView中, 因为cell的reuse会使其失效. 其实是Runloop Mode的原因.
// 修改mode, 这样滚动的时候也可接收其他runloop的消息了.
NSRunLoop.currentRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes)
使用NSURLConnection的initWithRequest的时候, 创建异步请求线程和NSTimer一样,也是NSDefaultRunLoopMode的.
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)
connection.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes)
connection.start()
Demo
Demo地址: DemoNSTimer