iOS---->CADisplayLink、比NSTimer更精确的定时器
什么是CADisplayLink
CADisplayLink是一个能让我们以和屏幕刷新率相同的频率将内容画到屏幕上的定时器。我们在应用中创建一个新的 CADisplayLink 对象,把它添加到一个runloop中,并给它提供一个 target 和selector 在屏幕刷新的时候调用。
一但 CADisplayLink 以特定的模式注册到runloop之后,每当屏幕需要刷新的时候,runloop就会调用CADisplayLink绑定的target上的selector,这时target可以读到 CADisplayLink 的每次调用的时间戳,用来准备下一帧显示需要的数据。例如一个视频应用使用时间戳来计算下一帧要显示的视频数据。在UI做动画的过程中,需要通过时间戳来计算UI对象在动画的下一帧要更新的大小等等。
在添加进runloop的时候我们应该选用高一些的优先级,来保证动画的平滑。可以设想一下,我们在动画的过程中,runloop被添加进来了一个高优先级的任务,那么,下一次的调用就会被暂停转而先去执行高优先级的任务,然后在接着执行CADisplayLink的调用,从而造成动画过程的卡顿,使动画不流畅。
duration属性提供了每帧之间的时间,也就是屏幕每次刷新之间的的时间。我们可以使用这个时间来计算出下一帧要显示的UI的数值。但是 duration只是个大概的时间,如果CPU忙于其它计算,就没法保证以相同的频率执行屏幕的绘制操作,这样会跳过几次调用回调方法的机会。frameInterval属性是可读可写的NSInteger型值,标识间隔多少帧调用一次selector 方法,默认值是1,即每帧都调用一次。如果每帧都调用一次的话,对于iOS设备来说那刷新频率就是60HZ也就是每秒60次,如果将 frameInterval 设为2 那么就会两帧调用一次,也就是变成了每秒刷新30次。
我们通过pause属性开控制CADisplayLink的运行。当我们想结束一个CADisplayLink的时候,应该调用-(void)invalidate
从runloop中删除并删除之前绑定的 target跟selector
另外CADisplayLink 不能被继承。
CADisplayLink 与 NSTimer 有什么不同
iOS设备的屏幕刷新频率是固定的,CADisplayLink在正常情况下会在每次刷新结束都被调用,精确度相当高。NSTimer的精确度就显得低了点,比如NSTimer的触发时间到的时候,runloop如果在阻塞状态,触发时间就会推迟到下一个runloop周期。并且 NSTimer新增了tolerance属性,让用户可以设置可以容忍的触发的时间的延迟范围。CADisplayLink使用场合相对专一,适合做UI的不停重绘,比如自定义动画引擎或者视频播放的渲染。NSTimer的使用范围要广泛的多,各种需要单次或者循环定时处理的任务都可以使用。在UI相关的动画或者显示内容使用 CADisplayLink比起用NSTimer的好处就是我们不需要在格外关心屏幕的刷新频率了,因为它本身就是跟屏幕刷新同步的。
哈哈哈
CADisplayLink使用的例子
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateTextColor)];
self.displayLink.paused = YES;
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
-(void)updateTextColor{}
- (void)startAnimation{
self.beginTime = CACurrentMediaTime();
self.displayLink.paused = NO;
}
- (void)stopAnimation{
self.displayLink.paused = YES;
[self.displayLink invalidate];
self.displayLink = nil;
}
给非UI对象添加动画效果
我们知道动画效果就是一个属性的线性变化,比如UIView 动画的 EasyIn EasyOut 。通过数值按照不同速率的变化我们能生成更接近真实世界的动画效果。我们也可以利用这个特性来使一些其他属性按照我们期望的曲线变化。比如当播放视频时关掉视频的声音我可以通过CADisplayLink来实现一个 EasyOut的渐出效果:先快速的降低音量,在慢慢的渐变到静音。
注意
通常来讲:iOS设备的刷新频率事60HZ也就是每秒60次。那么每一次刷新的时间就是1/60秒 大概16.7毫秒。当我们的frameInterval值为1的时候我们需要保证的是 CADisplayLink调用的`target`的函数计算时间不应该大于 16.7否则就会出现严重的丢帧现象。
在mac应用中我们使用的不是CADisplayLink而是 CVDisplayLink它是基于C接口的用起来配置有些麻烦但是用起来还是很简单的。
Apple官方的Demo
CADisplayLink Clas Reference
一个类似Secret文字渐变效果的开源库
iOS---->CADisplayLink、比NSTimer更精确的定时器的更多相关文章
- iOS - CADisplayLink与NSTimer
一.CADisplayLink简介 CADisplayLink 是一个定时器对象可以让你的应用以与显示器的刷新界面相同的频率进行绘图. 应用如果想要创建 display link ,需要提供一个目标对 ...
- iOS开发中深入理解CADisplayLink和NSTimer
一.什么是CADisplayLink 简单地说,它就是一个定时器,每隔几毫秒刷新一次屏幕. CADisplayLink是一个能让我们以和屏幕刷新率相同的频率将内容画到屏幕上的定时器.我们在应用中创建一 ...
- IOS中的NSTimer定时器详解
/* 在IOS中有多种定时器,这里我对NSTimer定时器做了一个简单的介绍.如果你是小白,你可能会从这篇文章中学习到一些知识,如果你是大牛,请别吝啬你的评论,指出我的不足,你的质疑是对我最大的帮助. ...
- 深入理解CADisplayLink和NSTimer
一.什么是CADisplayLink 简单地说,它就是一个定时器,每隔几毫秒刷新一次屏幕. CADisplayLink是一个能让我们以和屏幕刷新率相同的频率将内容画到屏幕上的定时器.我们在应用中创建一 ...
- iOS 中的 NSTimer
iOS 中的 NSTimer NSTimer fire 我们先用 NSTimer 来做个简单的计时器,每隔5秒钟在控制台输出 Fire .比较想当然的做法是这样的: @interface Detail ...
- CADisplayLink、NSTimer循环引用解决方案
前言:CADisplayLink.NSTimer 循环引用问题 CADisplayLink.NSTimer会对Target产生强引用,如果target又对他们产生强引用,那么就会引发循环引用. @ ...
- nanosleep() -- 更精确的延迟 -----一个使用用例
[常规] nanosleep() -- 更精确的延迟 [复制链接] beyes 4220 主题 5152 帖子 3万 积分 GROAD 曲径通幽,安觅芳踪. 积分 30607 发消息 电梯直达 ...
- Mac 上 QuickTime Player 播放器以 1.1、1.2 倍速等更精确速度快进/快退播放的方法
苹果的 QuickTime Player 播放器上点击双箭头按钮可以用 2.4.8 倍的速度快进/快退播放视频,但是 2 倍速太快了,如果我想以 1.1.1.2 倍速这种更精确的速度控制视频播放呢?按 ...
- iOS开发--计时器-NSTimer与CADisplayLink
如果程序要让某个方法重复执行,可以借助定时器来完成.CADisplayLink是一个能让我们以和屏幕刷新率相同的频率将内容画到屏幕上的定时器,NSTimer的精确度低了点,比如NSTimer的触发时间 ...
随机推荐
- LeetCode House Robber 家庭劫犯(dp)
题意:有一个整数序列,从中挑出一些数字,使得总和是最大,前提是,相邻的两个数字中只能挑其一.比如1 2 3 就只能挑2或者1和3. 思路:很直观的题,dp思想.降低规模,从小规模开始考虑.如果只有两个 ...
- HDU 4738 Caocao's Bridges taijan (求割边,神坑)
神坑题.这题的坑点有1.判断连通,2.有重边,3.至少要有一个人背*** 因为有重边,tarjan的时候不能用子结点和父节点来判断是不是树边的二次访问,所以我的采用用前向星存边编号的奇偶性关系,用^1 ...
- UVA 690 PipelineScheduling 位运算+dfs+剪枝
一开始最容易想到间隔最多为n,但是结点还是太多了,需要优化. 预处理:预判一下并保存下一个可以放的位置距离之前的距离.这样可以减少很多判断. 最优化剪枝:如果当前长度+剩下没放的程序*最短间隔如果大于 ...
- Android(java)学习笔记112:Activity中的onCreate()方法分析
1.onCreate( )方法是android应用程序中最常见的方法之一: 翻译过来就是说,onCreate()函数是在activity初始化的时候调用的,通常情况下,我们需要在onCreate()中 ...
- Mycat实现读写分离、分库分表
系统开发中,数据库是非常重要的一个点.除了程序的本身的优化,如:SQL语句优化.代码优化,数据库的处理本身优化也是非常重要的.主从.热备.分表分库等都是系统发展迟早会遇到的技术问题问题.Mycat是一 ...
- 二、antd pro 删除eslint检测
删除package.json 里 " pre-commit": "npm run lint-staged" 这个对象就可以.
- python_80_模块定义导入优化实例
运行结果 __import__作用: 同import语句同样的功能,但__import__是一个函数,并且只接收字符串作为参数,所以它的作用就可想而知了.其实import语句就是调用这 ...
- Linux运维笔记--第三部
第三部 3. Linux系统文件重要知识初步讲解 # ls -lhi (i: inode,每个文件前的数字代表文件身份ID:h: human 人类可读) 显示:25091 -rw-r--r-- ...
- 微信小程序传值取值的几种方法
一,列表index下的取值 实现方式是:data-index="{{index}}"挖坑及e.currentTarget.dataset.index来填坑即可 1.1生成值 < ...
- Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.
文档:Docker 启动错误.note链接:http://note.youdao.com/noteshare?id=065111d506e1b132dc930dbe88f5d7b0&sub=A ...