一、介绍

在iOS中,计时器是比较常用的,用于统计累加数据或者倒计时等,例如手机号获取验证码。计时器大概有那么三种,分别是:NSTimer、CADisplayLink、dispatch_source_t

二、使用

@property (strong,nonatomic)NSTimer *timer;
@property (strong,nonatomic)CADisplayLink *displaylinkTimer;
@property (strong,nonatomic)dispatch_source_t sourceTimer;

1、NSTimer:

//NSTimer
-(void)createTimer{ //初始化
//_timer = [NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
//执行操作
//}]; _timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerStart:) userInfo:nil repeats:YES]; //加入runloop循环池
[[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSDefaultRunLoopMode]; //开启定时器
[_timer fire];
}
-(void)timerStart:(NSTimer *)timer{
NSLog(@"%s-----%lf",__func__,timer.timeInterval); //销毁定时器
//[_timer invalidate];
//_timer = nil;
}

解释:

  • TimerInterval: 执行之前等待的时间。比如设置成1.0,就代表1秒后执行方法
  • target: 需要执行方法的对象。
  • selector : 需要执行的方法
  • repeats : 是否需要循环

注意 :
调用创建方法后,target对象的计数器会加1,直到执行完毕,自动减1。如果是循环执行的话,就必须手动关闭,否则可以不执行释放方法。

特性:

  • 存在延迟
  • 不管是一次性的还是周期性的timer的实际触发事件的时间,都会与所加入的RunLoop和RunLoop Mode有关,如果此RunLoop正在执行一个连续性的运算,timer就会被延时出发。重复性的timer遇到这种情况,如果延迟超过了一个周期,则会在延时结束后立刻执行,并按照之前指定的周期继续执行。
  • 必须加入Runloop

使用上面的创建方式,会自动把timer加入MainRunloop的NSDefaultRunLoopMode中。如果使用以下方式创建定时器,就必须手动加入Runloop:

NSTimer *timer = [NSTimer timerWithTimeInterval: target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

2、CADisplayLink:

//CADisplayLink
-(void)createCADisplayLink{ _displaylinkTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)];
[_displaylinkTimer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
-(void)handleDisplayLink:(CADisplayLink *)displaylinkTimer{
NSLog(@"%s-----%ld",__func__,displaylinkTimer.preferredFramesPerSecond); //销毁定时器
//[_displaylinkTimer invalidate];
//_displaylinkTimer = nil;
}

解释:

当把CADisplayLink对象add到runloop中后,selector就能被周期性调用,类似于重复的NSTimer被启动了;执行invalidate操作时,CADisplayLink对象就会从runloop中移除,selector调用也随即停止,类似于NSTimer的invalidate方法。

特性:

  • 屏幕刷新时调用CADisplayLink是一个能让我们以和屏幕刷新率同步的频率将特定的内容画到屏幕上的定时器类。CADisplayLink以特定模式注册到runloop后,每当屏幕显示内容刷新结束的时候,runloop就会向CADisplayLink指定的target发送一次指定的selector消息, CADisplayLink类对应的selector就会被调用一次。所以通常情况下,按照iOS设备屏幕的刷新率60次/秒
  • 延迟iOS设备的屏幕刷新频率是固定的,CADisplayLink在正常情况下会在每次刷新结束都被调用,精确度相当高。但如果调用的方法比较耗时,超过了屏幕刷新周期,就会导致跳过若干次回调调用机会。如果CPU过于繁忙,无法保证屏幕60次/秒的刷新率,就会导致跳过若干次调用回调方法的机会,跳过次数取决CPU的忙碌程度。

使用场景:

  • 从原理上可以看出,CADisplayLink适合做界面的不停重绘,比如视频播放的时候需要不停地获取下一帧用于界面渲染。

重要属性:

  • frameInterval(已过时,用preferredFramesPerSecond替代)  NSInteger类型的值,用来设置间隔多少帧调用一次selector方法,默认值是1,即每帧都调用一次。
  • duration  readOnly的CFTimeInterval值,表示两次屏幕刷新之间的时间间隔。需要注意的是,该属性在target的selector被首次调用以后才会被赋值。selector的调用间隔时间计算方式是:调用间隔时间 = duration × frameInterval。

3、dispatch_source_t:

//dispatch_source_t
-(void)createDispatch_source_t{ //创建全局队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ); //使用全局队列创建计时器
_sourceTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, , , queue); //定时器延迟时间
NSTimeInterval delayTime = 1.0f; //定时器间隔时间
NSTimeInterval timeInterval = 1.0f; //设置开始时间
dispatch_time_t startDelayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayTime * NSEC_PER_SEC)); //设置计时器
dispatch_source_set_timer(_sourceTimer,startDelayTime,timeInterval*NSEC_PER_SEC,0.1*NSEC_PER_SEC); //执行事件
dispatch_source_set_event_handler(_sourceTimer,^{ //销毁定时器
//dispatch_source_cancel(_myTimer);
}); //启动计时器
dispatch_resume(_sourceTimer);
}

特性:

  • 默认是重复执行的,可以在事件响应回调中通过dispatch_source_cancel方法来设置为只执行一次,如下代码:
dispatch_source_set_event_handler(_timer, ^{
//执行事件
dispatch_source_cancel(_timer);}
);

重要属性:

dispatch_source_set_timer(dispatch_source_t source,
dispatch_time_t start,
uint64_t interval,
uint64_t leeway);
  • start计时器起始时间,可以通过dispatch_time创建,如果使用DISPATCH_TIME_NOW,则创建后立即执行
  • interval计时器间隔时间,可以通过timeInterval * NSEC_PER_SEC来设置,其中,timeInterval为对应的秒数
  • leeway这个参数的理解,我觉得http://www.dreamingwish.com上Seven's同学的解释很直观也很易懂:“这个参数告诉系统我们需要计时器触发的精准程度。所有的计时器都不会保证100%精准,这个参数用来告诉系统你希望系统保证精准的努力程度。如果你希望一个计时器没五秒触发一次,并且越准越好,那么你传递0为参数。另外,如果是一个周期性任务,比如检查email,那么你会希望每十分钟检查一次,但是不用那么精准。所以你可以传入60,告诉系统60秒的误差是可接受的。这样有什么意义呢?简单来说,就是降低资源消耗。如果系统可以让cpu休息足够长的时间,并在每次醒来的时候执行一个任务集合,而不是不断的醒来睡去以执行任务,那么系统会更高效。如果传入一个比较大的leeway给你的计时器,意味着你允许系统拖延你的计时器来将计时器任务与其他任务联合起来一起执行。

优点:

  • 时间准确
  • 可以使用子线程,解决定时间跑在主线程上卡UI问题

注意事项:

  • 需要将dispatch_source_t timer设置为成员变量,不然会立即释放

三、参考原链接:

http://www.jianshu.com/p/53c07eb57223

iOS:三种常见计时器(NSTimer、CADisplayLink、dispatch_source_t)的使用的更多相关文章

  1. iOS开发--计时器-NSTimer与CADisplayLink

    如果程序要让某个方法重复执行,可以借助定时器来完成.CADisplayLink是一个能让我们以和屏幕刷新率相同的频率将内容画到屏幕上的定时器,NSTimer的精确度低了点,比如NSTimer的触发时间 ...

  2. 浅析NSTimer & CADisplayLink内存泄露

    偶得前言 NSRunLoop与定时器 - invalidate的作用 我们如何解决? 偶得前言 本篇文章中我们主要谈谈NSTimer\CADisplayLink在使用过程中牵扯到内存泄露的相关问题及解 ...

  3. 深入学习jQuery的三种常见动画效果

    × 目录 [1]显隐效果 [2]高度变化 [3]淡入淡出 前面的话 动画效果是jQuery吸引人的地方.通过jQuery的动画方法,能够轻松地为网页添加视觉效果,给用户一种全新的体验.jQuery动画 ...

  4. Android应用开发中三种常见的图片压缩方法

    Android应用开发中三种常见的图片压缩方法,分别是:质量压缩法.比例压缩法(根据路径获取图片并压缩)和比例压缩法(根据Bitmap图片压缩). 一.质量压缩法 private Bitmap com ...

  5. 三种常见的部署Kubernetes的方式

    三种常见的部署Kubernetes的方式 嘹亮的小号 Ghostcloud-001工号,资深Docker玩家,分布式系统研发11年. ​关注他   容器技术将应用程序及其依赖关系与操作系统进行分离,不 ...

  6. Spring源码分析之IOC的三种常见用法及源码实现(二)

    Spring源码分析之IOC的三种常见用法及源码实现(二) 回顾上文 我们研究的是 AnnotationConfigApplicationContext annotationConfigApplica ...

  7. iOS开发中深入理解CADisplayLink和NSTimer

    一.什么是CADisplayLink 简单地说,它就是一个定时器,每隔几毫秒刷新一次屏幕. CADisplayLink是一个能让我们以和屏幕刷新率相同的频率将内容画到屏幕上的定时器.我们在应用中创建一 ...

  8. ios 中定时器:NSTimer, CADisplayLink, GCD

    #import "ViewController.h" #import "RunloopViewController.h" @interface ViewCont ...

  9. 【转】IOS 计时器 NSTimer

    原文网址:http://blog.csdn.net/tangshoulin/article/details/7644124 1.初始化 + (NSTimer *)timerWithTimeInterv ...

随机推荐

  1. Lighthouse前端性能优化测试工具

    在前端开发中,对于自己开发的app或者web page性能的好坏,一直是让前端开发很在意的话题.我们需要专业的网站测试工具,让我们知道自己的网页还有哪些需要更为优化的方面,我自己尝试了一款工具:Lig ...

  2. js冲刺一下

    js中__proto__和prototype的区别和关系 1.对象有属性__proto__,指向该对象的构造函数的原型对象. 2.方法除了有属性__proto__,还有属性prototype,prot ...

  3. 开发人员如何正确对待BUG?

    ‌1.前端开发与后端开发 出了问题,最重要的是先找到方法迅速解决,而不是去互相指责.前端存在这样的思维模式,后端也存在这样的思维模式,这种思维模式不太好.出了问题,最好先检查一下自己,反省是不是自己这 ...

  4. hadoop 视频教程3之实战教程

    一,视频内容: 海量数据处理平台框架 hadoop介绍 hadoop 生态系统介绍 hdfs 设计原则 hdfs 系统架构 namenode datanode secondarynamenode hd ...

  5. RC4加密算法的原理及实现

    RC4于1987年提出,和DES算法一样.是一种对称加密算法,也就是说使用的密钥为单钥(或称为私钥). 但不同于DES的是.RC4不是对明文进行分组处理,而是字节流的方式依次加密明文中的每个字节.解密 ...

  6. VGA Signal Timing

    VGA Signal Timing 640 x 350 VGA 640x350@70 Hz (pixel clock 25.175 MHz) VESA 640x350@85 Hz (pixel clo ...

  7. TIMER门控模式控制PWM输出长度

    TIMER门控模式控制PWM输出长度 参照一些网友代码做了些修改,由TIM4来控制TIM2的PWM输出长度, 采用主从的门控模式,即TIM4输出高时候TIM2使能输出 //TIM2 PWM输出,由TI ...

  8. STM32F4XX devices vector table for EWARM toolchain.

    ;/******************** (C) COPYRIGHT 2015 STMicroelectronics ******************** ;* File Name : sta ...

  9. asp.net MVC 中 Session统一验证的方法

    验证登录状态的方法有:1  进程外Session   2 方法过滤器(建一个类继承ActionFilterAttribute)然后给需要验证的方法或控制器加特性标签 3 :新建一个BaseContro ...

  10. CRM上线之路 走上了CRM实施顾问-第12天上班 -第三周

    今天是周五,<CRM初期需求说明>是经理们商讨的,总共2张纸,根据两次会议,我写了<CRM需求说明>总共18面. 这是这周的工作汇报,其实,报告是我一天内写出来的,中午饭都没吃 ...