浅谈IOS屏幕刷新ADisplayLink

什么是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;
}

我们知道动画效果就是一个属性的线性变化,比如UIView 动画的EasyInEasyOut。通过数值按照不同速率的变化我们能生成更接近真实世界的动画效果。我们也可以利用这个特性来使一些其他属性按照我们期望的曲线变化。比如当播放视频时关掉视频的声音我可以通过CADisplayLink来实现一个EasyOut的渐出效果:先快速的降低音量,在慢慢的渐变到静音。

注意

通常来讲:iOS设备的刷新频率事60HZ也就是每秒60次。那么每一次刷新的时间就是1/60秒 大概16.7毫秒。当我们的frameInterval值为1的时候我们需要保证的是CADisplayLink调用的`target`的函数计算时间不应该大于 16.7否则就会出现严重的丢帧现象。

在mac应用中我们使用的不是CADisplayLink而是CVDisplayLink它是基于C接口的用起来配置有些麻烦但是用起来还是很简单的。

以上就是浅谈IOS屏幕刷新ADisplayLink的详细内容,更多关于IOS屏幕刷新ADisplayLink的资料请关注我们其它相关文章!

(0)

相关推荐

  • iOS蓝牙设备名称缓存问题的解决方法

    1. 问题背景 当设备已经在 App 中连接成功后 修改设备名称 App 扫描到的设备名称仍然是之前的名称 App 代码中获取名称的方式为(perpheral.name) 2. 问题分析 当 APP 为中心连接其他的蓝牙设备时. 首次连接成功过后,iOS系统内会将该外设缓存记录下来. 下次重新搜索时,搜索到的蓝牙设备时,直接打印 (peripheral.name),得到的是之前缓存中的蓝牙名称. 如果此期间蓝牙设备更新了名称,(peripheral.name)这个参数并不会改变,所以需要换一种方

  • iOS实现折叠单元格

    本文实例为大家分享了iOS实现折叠单元格的具体代码,供大家参考,具体内容如下 思路 点击按钮或cell单元格来进行展开收缩, 同时使用一个BOOL值记录单元格展开收缩状态.根据BOOL值对tableView的高度和button的image进行实时变更. 注意点: 在执行- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath( 点击当前单元格)方法时,收缩单元格,显示当前

  • iOS实现音乐播放器图片旋转

    本文实例为大家分享了iOS实现音乐播放器图片旋转的具体代码,供大家参考,具体内容如下 通过给继承与 UIImageView 的类 CXGImageView 添加 CABasicAnimation 转动动画,实现播放器图片转动效果. 主要提供三个方法: startRotating, stopRotating,resumeRotate startRotating /// 开始动画 func startRotating() { let rotateAnimation = CABasicAnimatio

  • iOS实现电子签名

    本文实例为大家分享了iOS实现电子签名的具体代码,供大家参考,具体内容如下 实现原理 1.使用拖动手势记录获取用户签名路径. 2.当用户初次接触屏幕,生成一个新的UIBezierPath,并加入数组中.设置接触点为起点.在手指拖动过程中为UIBezierPath添加线条,并重新绘制,生成连续的线. 3.手指滑动中不断的重新绘制,形成签名效果. 4.签名完成,转化为UIImage保存. class CXGSignView: UIView { var path: UIBezierPath? var

  • iOS键盘弹出遮挡输入框的解决方法

    本文为大家分享了iOS键盘弹出遮挡输入框的解决方法,供大家参考,具体内容如下 问题:输入框被键盘遮挡 期望效果:输入框位于键盘上方 解决思路: 监听键盘出现和消失的状态,当键盘出现时,当前视图上移,当输入完成收起键盘时,视图回到初始状态. 难点:视图向上平移的距离 原理都差不多,oc版参考代码: self.phoneInput = [UITextField new]; self.phoneInput.placeholder = @"请输入..."; [self.view addSubv

  • 详解iOS Method Swizzling使用陷阱

    在阅读团队一项目源码时,发现Method Swizzling的写法有些瑕疵.这篇文章主要就介绍iOS Method Swizzling的正确写法应该是什么样的. 下面是iOS Method Swizzling的一种实现: + (void)load { Class class = [self class]; SEL fromSelector = @selector(func); SEL toSelector = @selector(easeapi_func); Method fromMethod

  • iOS实现圆环比例图

    本文实例为大家分享了iOS实现圆环比例图的具体代码,供大家参考,具体内容如下 实现效果 实现方法 1. SSTCircleProgressView @interface SSTCircleProgressView : UIView /** *进度条的角的类型 */ @property (nonatomic,copy) CAShapeLayerLineCap lineCap; /** *进度条显示的文字 */ @property (nonatomic,copy) NSString *progres

  • iOS程序性能优化的技巧

    1. 用ARC管理内存 ARC(Automatic ReferenceCounting, 自动引用计数)和iOS5一起发布,它避免了最常见的也就是经常是由于我们忘记释放内存所造成的内存泄露.它自动为你管理retain和release的过程,所以你就不必去手动干预了.忘掉代码段结尾的release简直像记得吃饭一样简单.而ARC会自动在底层为你做这些工作.除了帮你避免内存泄露,ARC还可以帮你提高性能,它能保证释放掉不再需要的对象的内存. 2.尽量把views设置为透明 如果你有透明的Views你

  • iOS实现悬浮按钮

    前言 开发中会遇到有悬浮按钮功能. 效果 上代码 SuspensionButton.h #import <UIKit/UIKit.h> NS_ASSUME_NONNULL_BEGIN @interface SuspensionButton : UIButton @property(nonatomic, assign)BOOL MoveEnable; @property(nonatomic, assign)BOOL MoveEnabled; @property(nonatomic, assign

  • 浅谈IOS屏幕刷新ADisplayLink

    什么是CADisplayLink 我们在应用中创建一个新的CADisplayLink对象,把它添加到一个runloop中,并给它提供一个target和selector在屏幕刷新的时候调用. 一但CADisplayLink以特定的模式注册到runloop之后,每当屏幕需要刷新的时候,runloop就会调用CADisplayLink绑定的target上的selector,这时target可以读到CADisplayLink的每次调用的时间戳,用来准备下一帧显示需要的数据.例如一个视频应用使用时间戳来计

  • 浅谈iOS 屏幕方向那点事儿

    一般的应用,只会支持竖屏正方向一个方向,支持多个屏幕方向的应用还是比较少的. 不过我在工作的项目中,跟这个屏幕方向接触比较多,因为我们是一个有界面的 SDK,要让接入方接入的,一开始做没什么经验,考虑到接入方本身的屏幕方向可能是多种的,所以我们直接上来就支持四个方向,然后就是各种转屏的问题,90度旋转.180读旋转.270度旋转,测试手都快转断了. 后来觉的根本没必要,浪费了很多时间在解决屏幕方向的问题上,后来就简化到让接入方直接设置支持某个方向了. 一般的应用不用搞的这么的复杂,只要支持一两个

  • 浅谈iOS开发中static变量的三大作用

    (1)先来介绍它的第一条也是最重要的一条:隐藏 当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性.为理解这句话,我举例来说明.我们要同时编译两个源文件,一个是a.c,另一个是main.c. 下面是a.c的内容 char a = 'A'; // global variable void msg() { printf("Hello\n"); } 下面是main.c的内容 int main(void) { extern char a; // extern v

  • 浅谈iOS应用中的相关正则及验证

    1.手机号码的验证正则 正则表达式: ^((13[0-9])|(15[^4,\\D])|(18[0,0-9]))\\d{8}$ 详细解释 解释: •^...$: ^:开始 $:结束 中间为要处理的字串 •(13[0-9]): 以13开头接下来一位为0-9之间的数 13 : 以13开头 [0-9]:分割语法,13后面是0-9之间的数 •| : 或(or), 将前后两个匹配条件进行or运算 • (15[^4\\D]) : 以15开头接下来一位是除4之外的0-9数字 15 : 以15开头 [^4\\D

  • 浅谈iOS中几个常用协议 NSCopying/NSMutableCopying

    1.几点说明 说到NSCopying和NSMutableCopying协议,不得不说的就是copy和mutableCopy. 如果类想要支持copy操作,则必须实现NSCopying协议,也就是说实现copyWithZone方法; 如果类想要支持mutableCopy操作,则必须实现NSMutableCopying协议,也就是说实现mutableCopyWithZone方法; iOS系统中的一些类已经实现了NSCopying或者NSMutableCopying协议的方法,如果向未实现相应方法的系

  • 浅谈IOS如何对app进行安全加固

    防止 tweak 依附 通常来说,我们要分析一个 app,最开始一般是砸壳, $ DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /path/to/XXX.app/XXX 然后将解密之后的二进制文件扔给类似 hopper 这样的反编译器处理.直接将没有砸壳的二进制文件扔个 hopper 反编译出来的内容是无法阅读的(被苹果加密了).所以说砸壳是破解分析 app 的第一步.对于这一步的防范,有两种方式. 1.限制二进制文件头内的段 通过在 Xcode 里面工程配

  • 浅谈iOS解析HTMl标签以及开发中的一些坑

    开篇 看了看更新日期好久没写简书了,经常还有小伙伴在文章下面评论,看到自己写的东西还是有点用的,鼓励自己接着坚持下去吧,哈哈.今天主要就写写iOS中怎么解析HTML标签,我们常用的后台返回数据一般是json格式的但是有些时候如果我们收到的是带HTMl标签的我们该怎么处理他呢,今天就来说一说吧. 正文 前两天获取后台数据的时候,得到这么一条返回信息 "恭喜您获得<font color='red'>8.1元</font>现金奖励 " 本来简简单单的把返回数据展示到l

  • 浅谈iOS UIWebView对H5的缓存功能

    这两天在搞与H5交互的事,之前做的都是加载的静态的web页面,交互调试起来很快,这次搞的是js写的前端页面,跳转什么的都是动态的,然后就不响应了,搞了半天原来是缓存的问题,这里简单介绍一下,一般请求会使用下面的方法: + (instancetype)requestWithURL:(NSURL *)URL; 该方法的描述如下: Creates and returns a URL request for a specified URL with default cache policy and ti

  • 浅谈iOS中三种生成随机数方法

    ios 有如下三种随机数方法: //第一种 srand((unsigned)time(0)); //不加这句每次产生的随机数不变 int i = rand() % 5; //第二种 srandom(time(0)); int i = random() % 5; //第三种 int i = arc4random() % 5 ; 注: ① rand()和random()实际并不是一个真正的伪随机数发生器,在使用之前需要先初始化随机种子,否则每次生成的随机数一样. ② arc4random() 是一个

  • 浅谈IOS中AFNetworking网络请求的get和post步骤

    1.首先通过第三方:CocoaPods下载AFNetworking 1.1.先找到要查找的三方库:pod search + AFNetworking 1.2.出来一堆列表页面,选择三方库最新版本命令,例如: pod 'MBProgressHUD','~>0.8'  (:q 返回) 1.3.创建工程,进入工程: cd + 工程路径 1.4.编辑工程的Podfile文件: vim Podfile 1.5.(platform :iOS, '8.0'
target "工程名" do
po

随机推荐