在iOS中我们常用的定时器有三种: Timer, CADisplayLink, DispatchSourceTimer
Timer是我们最常见的亏渗消定时器,当定时器创建完(不用 scheduled 的,需要手动添加到 runloop 中)后,该定时器将在初始化时指定的 t 秒后自动触发。我们经常围绕它的俩个问题是 精度 和 循环引用 问题。
如果Timer是加在销知main runloop中,就很容易因为主线程忙于各种UI *** 作或者复杂的运算导喊明致阻塞线程,从而使得NSTimer延迟执行,导致精度较低。
Timer如果想要更高点的精度,我们可以从以下几个方面考虑
我们知道Timer的调用有target-action和block俩种方式,其中target-action会导致循环引用,造成内存泄露的问题, 因为target, action,runLoop之间有强引用链导致,解决办法
1.使用block回调方式
2.使用NSProxy类作为中间对象
CADisplayLink通过和屏幕刷新相同的频率将内容显示到屏幕上。也是依赖于NSRunLoop运行,iOS设备的屏幕刷新频率是固定的,CADisplayLink在通常都会在在每次刷新结束调用,精度较高,更适合做屏幕刷新等
DispatchSourceTimer精度很高,因为是系统级别,且是不受RunLoop影响。
常见基础用法
以旦拆握iphone6手机为例
*** 作步骤
1、开始,先在手机的桌面上找到应用程序“时钟”图标,点击进入新的 *** 作界模庆面。
2、然后,进入到时钟的 *** 作界面后,找到“计时器”选项,点击打开。
3、进入到计时器的 *** 作界面后,找到“计时结束时启用”选项,点击打开。
4、进去以后,下拉到御码最下面,勾选“停止运行”。
5、调整好定时关机倒计时的时间,点击“开始计时”即可。
创建方式:
需要添通过 addTimer:forMode: 加到当前线程的runloop
如果只是执行延时 *** 作,可以用:
以上的所有方法创建的定时器,如果在子模团线程中运行是需要开启runloop的
影响正肢NSTimer的原因:
计时器对象,与屏幕的刷新率同步。
iOS 设备的屏幕刷新频率是固定的,其精度相当准确,一般用于做 UI 界面的不停重绘
GCD中的 dispatch_source 常见的场景就是定时器功能, dispatch_source_t 系统级的源事件,由系统自动触发,高精度
void dispatch_source_set_timer(dispatch_source_t source,dispatch_time_t start,uint64_t interval,uint64_t leeway)
参数1:source 创建的定时器timer
参数2:DISPATCH_TIME_NOW
DISPATCH_SOURCE_TYPE_TIMER系统会使用默认时钟来进行计时,当系统休眠的时候,默认时钟是不走的,也就会导致计时器停止。
dispatch_walltime(NULL,0)可以让计时器按照真实时间间隔进行计时。
参数3:间隔时间
参数4:容错,如果设置为1秒,系统可能会在任务时间到达前1秒或后1秒执行
创建好的定时器,需要手动开启:
等到指定的时间通过异步的方式将提其提交到指定的队列中执行
dispatch_time 第一个参数:dispatch_time_t
DISPATCH_TIME_NOW: 0
DISPATCH_TIME_FOREVER: 无穷大举码世
这里0.36代表 0.36秒之后执行任务
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)