一、NSTimer(存在延迟)
- 创建方法
let timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "updateCurrentProgress:", userInfo: nil, repeats: true)
TimerInterval : 执行之前等待的时间。比如设置成1.0,就代表1秒后执行方法
target : 需要执行方法的对象。
selector : 需要执行的方法
repeats : 是否需要循环
- 释放方法
timer.invalidate()
timer = nil
注意 :
调用创建方法后,target对象的计数器会加1,直到执行完毕,自动减1。如果是循环执行的话,就必须手动关闭,否则可以不执行释放方法。
首先关闭定时器不能使用上面的方法,应该使用下面的方法:
//关闭定时器
timer.setFireDate(NSDate.distantFuture());
然后就可以使用下面的方法再此开启这个timer了:
//开启定时器
timer.setFireDate(NSDate.distantPast())
- 特性
不管是一次性的还是周期性的timer的实际触发事件的时间,都会与所加入的RunLoop和RunLoop Mode有关,如果此RunLoop正在执行一个连续性的运算,timer就会被延时出发。重复性的timer遇到这种情况,如果延迟超过了一个周期,则会在延时结束后立刻执行,并按照之前指定的周期继续执行。
必须加入Runloop
使用上面的创建方式,会自动把timer加入MainRunloop的NSDefaultRunLoopMode中。如果使用以下方式创建定时器,就必须手动加入Runloop:
let timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "updateCurrentProgress:", userInfo: nil, repeats: true)
NSRunLoop.mainRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes)
二、CADisplayLink(屏幕刷新时调用)
- 创建方法
self.displayLink = CADisplayLink(target: self, selector: "updateCurrentProgress")
self.displayLink?.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes)
- 停止方法
self.displayLink?.invalidate()
self.displayLink = nil
CADisplayLink是一个能让我们以和屏幕刷新率同步的频率将特定的内容画到屏幕上的定时器类。CADisplayLink以特定模式注册到runloop后,每当屏幕显示内容刷新结束的时候,runloop就会向CADisplayLink指定的target发送一次指定的selector消息, CADisplayLink类对应的selector就会被调用一次。所以通常情况下,按照iOS设备屏幕的刷新率60次/秒
使用场景
从原理上可以看出,CADisplayLink适合做界面的不停重绘,比如视频播放的时候需要不停地获取下一帧用于界面渲染。