美文网首页
iOS定时器看我就够了

iOS定时器看我就够了

作者: 沈正方 | 来源:发表于2018-03-12 10:25 被阅读26次

    这篇文章总结iOS开发中用到的全部和定时器相关的内容,用到某个定时器就会总结一下,所以持续更新中~

    CADisplayLink

    CADisplayLink介绍

    • CADisplayLink定时器在屏幕刷新时调用方法做事情。

    CADisplayLink使用场景

    • 根据其调用方法的时机的特点(屏幕刷新时调用),可以结合setNeedDisplay(调用drawRect方法,drawRect方法会在屏幕刷新时重绘屏幕的内容)实现很流畅的动画效果。
    let displayLink = CADisplayLink(target: self, selector: #selector(update))
    displayLink.add(to: RunLoop.main, forMode: RunLoopMode.commonModes)
    
    func update() {
        // 改变某个变量,实现移动内容的位置,实现动画效果
        ......
    
        /*
         * setNeedsDisplay方法在屏幕刷新时会调用drawRect方法
         * 因为定时器CADisplayLink执行方法的时间(屏幕刷新时)和setNeedDisplay调用drawRect方法(屏幕刷新时重绘)的时间是一致的。所以动画会很流畅
         * 适用的场景:二维码扫描的“扫描线”
         */
        self.setNeedsDisplay()
    }
    

    Timer

    概述
    Timers结合RunLoop一起使用,RunLoop会强引用加入RunLoop的定时器,因此你不需要手动(比如通过属性的方式)强引用定时器。

    如果想要高效的使用Timer,你需要了解RunLoop是如何工作的。点击Threading Programming Guide了解更多关于线程和RunLoop的信息。

    Timer不是实时触发的机制,当一个Timer处在一个长时间循环RunLoop中或者当前RunLoop不是Timer加入的RunLoop时,定时器都有可能被延迟触发。当当前RunLoop正是Timer加入的RunLoop时,RunLoop会在每次运行循环时检查是否触发Timer

    你可以在创建的时候,指定Timer是否重复触发。一个不重复触发的定时器触发一次后就会被自动销毁,以此防止定时器再一次触发。
    相反,一个重复触发的定时器总是在新的一次RunLoop循环中重新根据RunLoop开始的时间设置自己的触发时间。而不是预计的时间。
    简单来说就是,比如定时器理论上在10、15、20、25……被触发。第一次在第10秒触发,下一次因为某种原因(切换运行模式)延迟了,导致23秒才触发一次,相当于跳过15秒和20秒,那么如果再一次不被延迟,理论上是25秒触发,不会因为23秒触发一次,就导致变成28秒触发。

    在iOS7和mac OS 10.0之后新增了一个Tolerance属性,可以为定时器指定一个Tolerance(允许误差的时间,默认为0)。
    这种允许误差带来的灵活性,当一个定时器触发时,提高了系统优化电量消耗和事件响应的能力。
    定时器可以在预定的触发时间和预定触发时间加上Tolerance之间的任何时间触发。定时器不会在预定的时间之前触发。
    当使用定时器的时候,Tolerance的值一般是时间间隔的10%,比如Timer每个5秒触发一次,那么Tolerance为1秒。即使Tolerance很小,也对系统的优化电源消耗能力有大的作用。

    Timer的使用

    创建定时的三种方式

    1. init(timeInterval ti: TimeInterval, target aTarget: Any, selector aSelector: Selector, userInfo: Any?, repeats yesOrNo: Bool)通过这种方式创建的Timer需要手动添加到RunLoop中。
    2. class func scheduledTimer(timeInterval ti: TimeInterval, target aTarget: Any, selector aSelector: Selector, userInfo: Any?, repeats yesOrNo: Bool) -> Timer通过这种方式创建Timer,Timer默认被添加到Default Mode。
    3. public init(fireAt date: Date, interval ti: TimeInterval, target t: Any, selector s: Selector, userInfo ui: Any?, repeats rep: Bool)通过这种方式创建的Timer需要手动添加到RunLoop中。

    相关文章

      网友评论

          本文标题:iOS定时器看我就够了

          本文链接:https://www.haomeiwen.com/subject/yqxjfftx.html