iOS - CADisplayLink与NSTimer

作者:Mitchell 

一、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 DocumentNSRunLoopThreading 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:or scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: 类方法创建计时器,将它以默认的模式预设在当前的 run loop 中。
      • timerWithTimeInterval:invocation:repeats:or timerWithTimeInterval: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 会将计时器移除(与它的强引用一起移除),一旦被移除,计时器对象就不能再使用。
  • 子类注意

    • 不能够继承 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,因为由于每秒的刷新频率较高,所以用它所生成的动画会显得非常流畅。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容