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中再通知恢复定时器。
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()