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()