iOS --- 使用NSTimer設定定時任務的注意事項
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()