iOS中的3种定时器

博客 分享
0 274
优雅殿下
优雅殿下 2023-05-10 20:54:57
悬赏:0 积分 收藏

iOS中的3种定时器

在iOS中有3种常见的定时器,它们会根据不同的场景进行选择使用。
1.DispatchSourceTimer: 基于GCD实现。
2.CADisplayLink:基于屏幕刷新实现。
3.Timer:基于RunLoop实现。

DispatchSourceTimer定时器
DispatchSourceTimer定时器可以通过DispatchSource.makeTimerSource(queue: DispatchQueue.main)方法来创建,并且
使用GCD创建了一个DispatchSource类型的定时器,并使用全局队列来运行它。通过schedule(deadline: .now(), repeating: .seconds(1))方法指定定时器的初始延迟和重复时间,然后设置了一个事件处理程序来定义定时器要执行的操作。
最后timer.resume()启动定时器。
要停止定时器,可以调用timer.cancel()方法。
优点为:Dispatch定时器非常轻量级,基于GCD的实现,可以利用GCD的优势来进行任务调度,性能高。
var timer: DispatchSourceTimer?
func startCountdown() {
    //一般倒计时是操作UI,使用主队列
    timer = DispatchSource.makeTimerSource(queue: DispatchQueue.main)
    // //耗时操作放在全局队列,子线程处理
    // timer = DispatchSource.makeTimerSource(queue: DispatchQueue.global())
    timer.schedule(deadline: .now(), repeating: .seconds(1))
    timer.setEventHandler {
        // 定时器执行的操作
    }
    timer.resume()
}

deinit {
    timer.cancel()
    timer = nil
}
CADisplayLink定时器
CADisplayLink定时器可以通过CADisplayLink(target: self, selector: #selector(update))方法创建,并且通过displayLink.add(to: .main, forMode: .common)方法将定时器添加到主运行循环中,并指定了运行模式。
然后定义update方法,该方法将在每个定时器周期中执行。
在对象销毁前停止定时器,可以调用displayLink.invalidate()方法。
CADisplayLink对象一旦创建就会运行,比较适合监控主线程UI卡顿,用做倒计时不如使用DispatchSourceTimer
它是和屏幕刷新率同步,优点在于精确度高,适用于需要频繁更新UI的场景。
var displayLink: CADisplayLink?
func startCountdown() {
    //一般倒计时是操作UI,使用主队列
    let displayLink = CADisplayLink(target: self, selector: #selector(update))
    //设置多长时间回调一次,默认每次刷新都会调用,大概60ps, 这里设置1表示1s调用一次
    displayLink.preferredFramesPerSecond = 1
    displayLink.add(to: .main, forMode: .common)
}

@objc func update() {
    // 定时器执行的操作
}

deinit {
    displayLink.invalidate()
    displayLink = nil
}
Timer定时器
Timer定时器可以使用Timer.scheduledTimer方法创建,然后指定重复间隔和一个闭包作为定时器要执行的操作。并且将返回的定时器对象存储在变量timer中。
要停止定时器,可以调用timer.invalidate()方法。
Timer是一个简单的定时器,基于RunLoop的,通常用于实现对实时性要求不高的场合,因为它被注册在runloop的timers事件源集合中,如果当前runloop执行耗时任务超过了调用时间,那么就会丢弃当前次,直接执行下一次。导致定时器不准时的情况。
var timer: Timer?
func startCountdown() {
    //一般倒计时是操作UI,使用主队列
    timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
    // 定时器执行的操作
    }
}

deinit {
    timer.invalidate()
    timer = nil
}

 

posted @ 2023-05-10 19:57  滴水微澜  阅读(4)  评论(0编辑  收藏  举报
回帖
    优雅殿下

    优雅殿下 (王者 段位)

    2017 积分 (2)粉丝 (47)源码

    小小码农,大大世界

     

    温馨提示

    亦奇源码

    最新会员