iOS中的3种定时器

iOS,定时器 · 浏览次数 : 191

小编点评

## Summary of Timing Mechanisms in iOS **Three common timers exist in iOS:** 1. **DispatchSourceTimer:** Uses GCD for efficient scheduling. 2. **CADisplayLink:** Syncs with screen refresh and ideal for precise UI updates. 3. **Timer:** Runs on RunLoop and suitable for situations with low-latency operations. **Here's a breakdown:** **DispatchSourceTimer:** * Lightweight and uses GCD for efficient scheduling. * Can schedule deadlines and repeat intervals. * Provides an event handler for scheduled operations. **CADisplayLink:** * Triggers on main thread and runs on screen refresh loop. * Highly accurate for UI updates. * Suitable for scenarios where precise timing is critical. **Timer:** * Runs on RunLoop thread. * Suitable for tasks with low-latency requirements. * Can be used for situations where real-time responsiveness is important. **Choosing the Right Timer:** * For **countdown tasks** that need to be executed **on the main thread**, use **DispatchSourceTimer**. * For **UI updates that are synchronized with screen refresh**, use **CADisplayLink**. * For **real-time tasks** with low latency, use **Timer**. **Additional Notes:** * Stop a timer using `cancel()` and set `timer` to `nil` to prevent memory leaks. * `CADisplayLink` can be stopped by calling `invalidate()`. * `Timer` can be stopped using `invalidate()` and set `timer` to `nil` to prevent memory leaks.

正文

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

DispatchSourceTimer定时器
DispatchSourceTimer定时器:
可以通过DispatchSource.makeTimerSource(queue: DispatchQueue.main)方法来创建。
然后通过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()方法。
它是和屏幕刷新率同步,优点在于精确度高,适用于需要频繁更新UI的场景。
CADisplayLink对象一旦创建就会运行,比较适合监控主线程UI卡顿。所以用做倒计时得场景下,更好的选择是使用DispatchSourceTimer定时器。
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
}

 

与iOS中的3种定时器相似的内容:

iOS中的3种定时器

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

Instruments中常用Template的使用

Instruments是苹果提供的Xcode套件,可用于分析iOS,MacOS程序的性能数据,进行性能提升。Instruments提供了很多类型的Template,用于特定场景的分析。这里选了3种常用的Template进行使用方法的讲解,对于其他Template的用法则用到时再了解吧,没必要一次把所

在原生APP中集成Unity容器

随着技术的发展,越来越多的APP期望拥有3D,AR的能力。要达到这个目标可以选择使用原生开发,也可以使用Unity成熟的3D开发技术链,通过嵌入的方式将Unity容器嵌入到APP中。这里介绍的是通过嵌入Unity容器的方式来实现APP的3D,AR能力的。 Unity集成到iOS应用的本质是将Unit

iOS安装包瘦身总结

前段时间APP要做资源压缩,需要把项目中使用的所有图片资源进行压缩,以减小APP安装包体积。想着既然压缩APP资源是为了缩小APP体积,那么来一遍APP整体瘦身流程并做一下总结吧。 整个过程分三步: 1.瘦身前分析 2.瘦身策略制定并实施 3.结果对比 瘦身前分析 安装包分析 iOS安装包有两种状态

iOS中容易用错的常用知识点

坐标系转换 ios中的坐标系有三种 视图坐标系:原点(0,0)视图的左上角 窗口坐标系:原点(0,0)窗口的左上角 世界坐标系:原点(0,0)游戏中世界的原点 平时开发中经常会遇到转UIWindow坐标问题,如:已知一个UI控件的坐标,把它转换到UIWindow时,它对应的UIWindow坐标是什么

flutter系列之:Navigator的高级用法

简介 上篇文章我们讲到了flutter中navigator的基本用法,我们可以使用它的push和pop方法来进行Router之间的跳转。 在flutter中一个Router就是一个widget,但是在Android中,一个Router就是Activity,在IOS中,一个Router是一个ViewC

iOS视图控件的内容显示和离屏渲染流程

iOS中UI控件内容显示流程 UIKit界面组成 iOS中组成页面的各个元素基本来自UIKit,我们可以修改布局或自定义绘制来修改UIKit元素的默认展示。 UIView的页面显示内容有CALayer负责,事件的接收与响应由UIView自己负责。 为什么需要有这样的分工呢,原因是因为Mac上和iPh

Swift中UITableViewDiffableDataSource的使用

在 iOS 13 中 Apple 为 UITableView 和 UICollectionView 引入了 DiffableDataSource, 让开发者可以更简单高效的实现 UITableView、UICollectionView 的局部数据刷新。 新的刷新的方法为 apply 通过使用 app

CocoaPods 在iOS开发中养活了这么多项目,它到底是个啥?

对于iOS开发者而言,CocoaPods并不陌生,通过pod相关的命令操作,就可以很方便的将项目中用到的三方依赖库资源集成到项目环境中,大大的提升了开发的效率。CocoaPods作为iOS项目的包管理工具,它在命令行背后做了什么操作?而又是通过什么样的方式将命令指令声明出来供我们使用的?这些实现的背后底层逻辑是什么?都是本文想要探讨挖掘的。

iOS开发基础102-后台保活方案

iOS系统在后台执行程序时,有严格的限制,为了更好地管理资源和电池寿命,iOS会限制应用程序在后台的运行时间。然而,iOS提供了一些特定的策略和技术,使得应用程序可以在特定场景下保持后台运行(即“后台保活”)。以下是iOS中几种常见的后台保活方案,并附上示例代码: 一、后台任务 利用beginBac