Swift定时Timer
Swift定时Timer

Swift定时Timer

Timer 是Swift 和 iOS/macOS 中用于定时执行任务的工具,用于创建和管理定时任务。它可以在指定的时间间隔内重复执行某些任务,或者在指定的时间之后执行一次任务。

基本用法

1、创建Timer

// 每2秒执行一次
let timer = Timer.scheduledTimer(withTimeInterval: 2.0, repeats: true) { timer in
    print("Timer fired!")
}

withTimeInterval表示时间间隔(秒),repeats表示是否重复,闭包可以访问timer对象。

注意:这种方式创建的Timer会自动加入当前RunLoop的默认模式。如果在滚动视图中使用Timer,可能会暂停,解决方案是指定模式:

RunLoop.current.add(timer, forMode: .common)

还有一种初始化方法:

let timer = Timer(timeInterval: 1.0, repeats: true) { _ in
    print("Hello Timer")
}
RunLoop.current.add(timer, forMode: .common)    // 手动加入 RunLoop,否则不会触发

创建后需要手动加入 RunLoop,否则不会触发,可用于点击开始计时的场景。

2、停止Timer

timer.invalidate()

调用invalidate() 后,Timer会被销毁,无法重新启动。

Timer.publish

在 Combine 框架中,Timer 提供了一种更现代化和响应式的方法来使用定时器。与传统的 Timer.scheduledTimer 或 Timer 构造器不同,它不是直接触发回调,而是返回一个 Combine 的 Publisher。这种机制更加适合 SwiftUI 的声明式和响应式编程风格。

1、创建Timer.publish

Timer.publish 把 Timer 变成了一个 Combine Publisher,可以订阅它的时间更新。

let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

every表示时间间隔(以秒为单位),on表示执行的线程(main主线程,currentdan当前线程.),in表示定时器运行循环模式(common常见模式,default默认模式,tracking仅滚动视图交互时使用)。

使用 .autoconnect() 会自动连接并开始发布事件,如果不调用autoconnect()则不会主动发出事件。

2、SwiftUI使用onReceive订阅

结合 SwiftUI 的 .onReceive,可以订阅这些事件:

.onReceive(timer) { time in
    print("Timer triggered at \(time)")
}

3、停止Timer.publish

timer.upstream.connect().cancel()

Timer和Timer.publish区别

1、Timer

触发方式:通过闭包回调(block),定时器触发时直接执行闭包。

运行循环:依赖运行循环管理。

手动管理:需要手动处理生命周期(invalidate())以及可能的线程切换(例如 UI 更新需要在主线程)。

// 传统方式的示例
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
    print("Timer fired!")
}

2、Combine 的 Timer.publish

触发方式:通过 Combine 的 Publisher,将事件发布为数据流。

运行循环:运行循环隐式处理,通过 Combine 自动适配。

自动管理:使用 .autoconnect() 后自动连接,无需手动管理开始或停止。

链式处理:可以结合 Combine 的操作符(如 map, filter, debounce 等)对事件流进行链式处理,代码更加简洁优雅。

// Combine 的方式
let timer = Timer.publish(every: 1.0, on: .main, in: .common).autoconnect()

timer.sink { date in
    print("The time is now \(date)")
}

注意事项

1、性能影响

定时器运行在主线程时,任务需要足够快地执行,避免阻塞主线程。

长时间运行的定时器可能影响设备的性能或电池寿命。

2、内存管理

定时器会强引用目标对象,可能导致内存泄漏。为避免这种情况,可以使用弱引用或确保及时调用 invalidate()。

Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in
    self?.doSomething()
}

总结

Timer 是一个功能强大的工具,适合定时任务或延时操作。在 SwiftUI 和现代应用开发中,通常结合 Combine 和运行循环一起使用,以实现更灵活的时间调度。

传统的 Timer 方法:更适合独立的定时任务,需要手动处理运行循环和生命周期管理。

Timer.publish 和 Combine:为响应式设计而生,更适合与 SwiftUI 搭配,尤其是在涉及到状态绑定和复杂数据流处理的场景中。

推荐使用 Timer.publish:如果项目是基于 SwiftUI 和 Combine 的,使用 Timer.publish 会更加自然高效。

   

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开发者。

欢迎加入我们的 微信交流群QQ交流群,交流更多精彩内容!
微信交流群二维码 QQ交流群二维码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注