iOS - CADisplayLink与NSTimer
一、CADisplayLink简介
- CADisplayLink 是一个定时器对象可以让你的应用以与显示器的刷新界面相同的频率进行绘图。
- 应用如果想要创建 display link ,需要提供一个目标对象和一个当屏幕刷新时被调用的选择器方法。之后再将 display link 添加到主线程中。
- 一旦display link与主线程相关联,当屏幕内容需要被刷新的时候目标对象上的选择器方法就会被调用。目标对象可以读取 display link 的时间戳属性去检索下一帧被显示的画面。举个例子,一个执行它自己动画的应用会使用时间戳来确定在哪或者如何去在即将显示的画面中去展示它的对象。
duration
属性提供了一个在两个画面之间的间隔时间。你可以在你的应用中使用这个值来估算显示的帧速率,近似下一帧被显示的时间,和调整行为,以便下一帧准备时间显示。 - 你的应用可以设置 paused 属性为YES来停止通知。同样的,如果你的应用不想用框架所提供的时间,你可以自己选择更慢的帧速率。已提供更慢但是一致的帧速率会比跳帧更加流畅,你可以通过改变
frameInterval
属性来改变改变画面的帧间隔(减少帧速率)。(每几帧调用一次,默认是1,如果是2,对于iOS设备来说那刷新频率就是60HZ也就是每秒60次,如果将 frameInterval 设为2 那么就会两帧调用一次,也就是变成了每秒刷新30次。) - 当你的应用想停止 display link ,它应该调用
invalidate
方法去从主线程中移除它并且消除与目标之间的关联。 CADisplayLink 不能被继承
。
二、NSTimer简介
- 使用 NSTimer 类创建定时器对象或者仅仅是计时器。一个计时器每隔一定的时间间隔运行,然后触发,发送给目标对象一个特殊的消息。举例来说,你能够创建一个 NSTimer 对象发送给窗口一个消息,告诉它在一定时间间隔之后更新它自己。
- 定时器的运行需要结合着 run Loop。为了有效的使用一个定时器,你应该注意如何操作 run loops。请搜索在
Xcode Document
中 NSRunLoop 和 Threading Programming Guide 文章。特别注意,run loops 对它们的定时器保持着强引用,所以你不必去对加到 run loop 中的定时器保持强引用。 - 计时器并不是一个真正的时间机制;它只有在被添加到循环运行模式中的一种的时候才能触发,此时计时器的触发时间一旦过去就能检查出。由于对各种输入源的一个典型run loop 管理,对于一个定时器的时间间隔的有效解决方案被限制在50-100毫秒,如果一个定时器的触发经历了很长的一段时间或者在一个 run loop 的模式下没能监控到计时器,则这个计时器不会触发直到下一次 run loop 再次检测出这个计时器。因此,真正的计时器触发时间可以在预定触发时间之后的很长一段时间之后。可以看看这篇文章 Timer Tolerance。
- 重复计时器与不可重复计时器
- 你可以在创建计时器的时候指定它是可重复的还是不可重复的。一个不可重复的计时器只触发一次然后自动销毁,从而防止计时器再次触发。与之相反,一个可重复的计时器会重复在相同的 run loop 中触发。
- 一个可重复的计时器总是按照预先设计的触发时间执行它自己,而不是实际的出发时间。举个例子,如果一个计时器将在特定的时间每5秒钟之后触发,预定触发时间将总会落后于开始的5秒时间间隔,即使实际的触发时间被推迟。如果到目前为止触发时间被推迟了很久已经错过了一个或者几个触发的时间点,计时器会在下一个触发周期上只触发一次;触发后计时器重新安排,为下一次触发做准备。
- 在 Run Loops 中预设定时器
- 一个定时器对象只能同事被注册在一个 run loop 中,虽然它能被添加到这个 run loop 中的多个 run loop 模式中去。有三种方式创建:
scheduledTimerWithTimeInterval:invocation:repeats:
orscheduledTimerWithTimeInterval:target:selector:userInfo:repeats:
类方法创建计时器,将它以默认的模式预设在当前的 run loop 中。timerWithTimeInterval:invocation:repeats:
ortimerWithTimeInterval:target:selector:userInfo:repeats:
类方法创建而没在 run loop 中预设它(创建之后,你必须将它添加到 run loop 中去,使用相应的 NSRunLoopaddTimer :forMode
方法)- 初始化计时器方法
initWithFireDate:interval:target:selector:userInfo:repeats:
- 一旦在 run loop 中预设了定时器,定时器就会在制定的时间间隔触发直到它被销毁。一个不重复的计时器会在触发之后自动被销毁。然而,对于一个重复的计时器,你必须调用它的 invaludate 方法来销毁它。调用这个方法会请求在 当前的 run loop 中将计时器移除;所以,你应该总在创建计时器的线程中来调用 invalidate 方法来销毁它。销毁计时器之后会立即让它无效所以不会再影响 run loop。然后在移除方法之前或者晚一点点 run loop 会将计时器移除(与它的强引用一起移除),一旦被移除,计时器对象就不能再使用。
- 一个定时器对象只能同事被注册在一个 run loop 中,虽然它能被添加到这个 run loop 中的多个 run loop 模式中去。有三种方式创建:
- 子类注意
不能够继承 NSTimer
。
Timer Tolerance:
- 在 iOS 7和 OSX v10.9 之后,你能够为定时器指定一个公差。让系统在计时器触发的时候更加灵活的提升优化系统并增加它的存储和响应的能力。计时器会在预定的时间和预定时间加上公差时间之内触发计时器。计时器不会在预定时间之前触发。对于重复计时器为了避免漂移,下次的触发时间是根据原始的触发时间所估算出来而公差只应用于单次的触发时间。默认值是0,意味着没有更多的公差。系统有权利对于一些计算器使用少量的公差而不管公差的属性值是多少。
- 作为计时器的使用者,也许你有一个对于计时器最合适的公差。一般的经验是对于可重复的计时器设置公差至少有10%的时间间隔。即使少量的公差也将对应用程序产生重大的积极影响。系统可能为公差设置一个最大值。
Toll-Free Bridging:
- 在Core Foundation框架和 Foundation 框架中有许多种数据类型可以被互换着使用。这种能力,被称为: Toll-Free Bridging,意味着你能够使用相同的数据类型作为 Core Foundation 方法调用的参数也可以作为一个OC 方法传递的接受者。举个例子:NSLocale 相对 Core Foundation 是的互换的类型是 CFLocale。因此,如果一个方法中的参数是 NSLocale* 类型的时候,你可以传递过去一个 CFLocaleRef,并且如果方法中的参数是 CGLocaleRef 参数,你可以传递过去一个 NSLocale 实例。
- NSRunLoop:
- NSRunLoop 类的声明是对于输入源的面向对象的编程思想。一个NSRunloop 对象处理着来自窗口系统、NSPort 对象和 NSConnection 对象的像鼠标或键盘事件的输入源。一个 NSRunloop 对象也能够处理 NSTimer 事件。
- 你的应用不能够创建或者显示的管理 NSRunLoop 对象。每个 NSThread 对象,包括应用的主线程,都有一个 NSRunLoop 对象由于需求被自动的创建。如果你需要访问当前线程的 run loop,你可以对 currentRunLoop 类做操作。
- 注意从 NSRunLoop的角度来看, NSTimer 对象并不是“输入源” - 他们是一种特殊类型,这意味着它们不会在触发的时候引起 run loop 返回。
注意: NSRunLoop 类一般不认为是线程安全的,其方法应该只在其当前的线程上下文中被调用。你不能尝试在别的线程中去调用 NSRunLoop 对象的方法,如果这样做将导致无法预料的结果。
小结
- 在动画中最好用CADisplayLink,因为由于每秒的刷新频率较高,所以用它所生成的动画会显得非常流畅。
iOS - CADisplayLink与NSTimer的更多相关文章
- iOS开发中深入理解CADisplayLink和NSTimer
一.什么是CADisplayLink 简单地说,它就是一个定时器,每隔几毫秒刷新一次屏幕. CADisplayLink是一个能让我们以和屏幕刷新率相同的频率将内容画到屏幕上的定时器.我们在应用中创建一 ...
- 深入理解CADisplayLink和NSTimer
一.什么是CADisplayLink 简单地说,它就是一个定时器,每隔几毫秒刷新一次屏幕. CADisplayLink是一个能让我们以和屏幕刷新率相同的频率将内容画到屏幕上的定时器.我们在应用中创建一 ...
- iOS 中的 NSTimer
iOS 中的 NSTimer NSTimer fire 我们先用 NSTimer 来做个简单的计时器,每隔5秒钟在控制台输出 Fire .比较想当然的做法是这样的: @interface Detail ...
- CADisplayLink、NSTimer循环引用解决方案
前言:CADisplayLink.NSTimer 循环引用问题 CADisplayLink.NSTimer会对Target产生强引用,如果target又对他们产生强引用,那么就会引发循环引用. @ ...
- iOS开发--计时器-NSTimer与CADisplayLink
如果程序要让某个方法重复执行,可以借助定时器来完成.CADisplayLink是一个能让我们以和屏幕刷新率相同的频率将内容画到屏幕上的定时器,NSTimer的精确度低了点,比如NSTimer的触发时间 ...
- ios 中定时器:NSTimer, CADisplayLink, GCD
#import "ViewController.h" #import "RunloopViewController.h" @interface ViewCont ...
- iOS中的NSTimer 和 Android 中的Timer
首先看iOS的, Scheduling Timers in Run Loops A timer object can be registered in only one run loop at a t ...
- IOS中的NSTimer定时器详解
/* 在IOS中有多种定时器,这里我对NSTimer定时器做了一个简单的介绍.如果你是小白,你可能会从这篇文章中学习到一些知识,如果你是大牛,请别吝啬你的评论,指出我的不足,你的质疑是对我最大的帮助. ...
- [置顶] ios 时间定时器 NSTimer应用demo
原创文章,转载请注明出处:http://blog.csdn.net/donny_zhang/article/details/9251917 demo功能:ios NSTimer应用demo .ipho ...
随机推荐
- CentOS查看CPU、内存、网络流量和磁盘 I/O【转载,待整理】
http://blog.csdn.net/zbyufei/article/details/6413273
- D3.js 简介和安装
一.What´s D3.js D3.js是一种数据操作类型的javascript库(也可视其为插件):结合HTML,SVG和CSS,D3可以图形化的,生动的展现数据. D3 的全称是(Data-Dri ...
- css-高度自适应的问题(body高度问题)
css-高度自适应的问题 对象height:100%并不能直接产生效果,是因为跟其父对象有关. #center{ height:100%; } 上面的css样式是无效的,不会产生任何效果. 需要改写: ...
- commonJS — 数组操作(for Array)
for Array github: https://github.com/laixiangran/commonJS/blob/master/src/forArray.js 代码 /** * Creat ...
- (转)HashMap分析
原文地址:http://www.cnblogs.com/ITtangtang/p/3948406.html HashMap的数据结构 HashMap的底层主要是基于数组和链表来实现的,它之所以有相当快 ...
- C++ Primer 第三章 标准库类型vector+迭代器iterator 运算
1.vector: 标准库类型vector表示对象的集合,其中所有对象的类型都相同,集合中的每个对象都有一个与之对应的索引,索引用于访问对象.因为vector“容纳着”其他对象,所以它也常被称作容器( ...
- java 多线程4(死锁)
死锁现象: 死锁原因: 1.存在两个或两个以上的线程. 2.存在两个或两个或两个以上的共享资源. 死锁现象解决的方案: 没有方案只能尽量避免.
- 【CITE】利用鼠标绘图C#
实例018 利用鼠标绘图 光盘位置:光盘\MR\01\018 在常用的画图软件中,用户一般都可以通过鼠标在其中绘图,那么该功能是如何实现的呢?本实例将讲解如何使用C#实现通过拖动鼠标在窗体上绘图的功能 ...
- 【转】Linux下XenServer管理工具安装
转载文章 - Linux下XenServer管理工具安装 Xen-Server 6.5 虚拟机安装Linux系统 vmware安装ubuntu12.04嵌套安装xen server(实现嵌套虚拟化) ...
- 初学java之StringBuffer类的常用方法
import java.text.*; public class Gxjun { public static void main(String atgs[]) { StringBuffer str= ...