1. 订阅者专属间隔:
每个订阅者独立记录上次触发时间和间隔
使用字典存储订阅者信息,Key为自动生成的UUID
2.精准触发机制:
全局定时器以1秒为基准间隔进行轮询
使用abs(timeIntervalSince)确保设备休眠时的时间计算正确
每次触发检查所有订阅者的间隔是否满足
3.立即触发支持:
通过immediate参数控制首次是否立即执行
自动管理首次触发时间的基准设置
4. 线程安全优化:
使用带barrier的并发队列保证订阅者字典的线程安全
事件回调自动切换到主线程处理UI操作
5. 内存管理:
结合Combine的AnyCancellable自动管理订阅生命周期
对象释放时自动取消订阅
import Foundation
import Combine
/// 全局定时器管理类(单例模式)
final class GlobalTimerManager {
// MARK: - 单例实例
static let shared = GlobalTimerManager()
// MARK: - 内部类型
private struct Subscriber {
let handler: (Date) -> Void
let interval: TimeInterval
var lastTriggerTime: Date?
}
// MARK: - 私有属性
private var timer: DispatchSourceTimer?
private var subscribers = [UUID: Subscriber]()
private let queue = DispatchQueue(
label: "com.globaltimer.manager",
attributes: .concurrent
)
private let timerQueue = DispatchQueue(
label: "com.globaltimer.timer",
qos: .utility
)
// MARK: - 定时器控制
/// 启动全局定时器(固定1秒间隔)
func start() {
queue.async(flags: .barrier) { [weak self] in
guard let self = self, self.timer == nil else { return }
let timer = DispatchSource.makeTimerSource(queue: self.timerQueue)
// 使用wall time保证设备休眠后的准确性
timer.schedule(
wallDeadline: .now(),
repeating: 1.0,
leeway: .milliseconds(50)
)
timer.setEventHandler { [weak self] in
self?.handleTimerTrigger()
}
timer.resume()
self.timer = timer
}
}
/// 停止定时器
func stop() {
queue.async(flags: .barrier) { [weak self] in
guard let self = self, let timer = self.timer else { return }
timer.cancel()
self.timer = nil
self.subscribers.removeAll()
}
}
// MARK: - 订阅管理
/// 订阅定时事件(默认不立即触发)
func subscribe(
interval: TimeInterval,
immediate: Bool = false,
_ handler: @escaping (Date) -> Void
) -> AnyCancellable {
let uuid = UUID()
let currentDate = Date()
// 初始化触发时间
var lastTriggerTime: Date?
if immediate {
// 立即触发并设置下次触发时间
DispatchQueue.main.async { handler(currentDate) }
lastTriggerTime = currentDate
} else {
// 设置初始触发基准时间
lastTriggerTime = currentDate
}
let subscriber = Subscriber(
handler: handler,
interval: interval,
lastTriggerTime: lastTriggerTime
)
queue.async(flags: .barrier) { [weak self] in
self?.subscribers[uuid] = subscriber
}
return AnyCancellable { [weak self] in
self?.unsubscribe(uuid: uuid)
}
}
// MARK: - 私有方法
private func handleTimerTrigger() {
let currentDate = Date()
printLog("全局定时器-主:\(currentDate)")
queue.sync { [weak self] in
guard let self = self else { return }
for (uuid, var subscriber) in self.subscribers {
guard let lastTime = subscriber.lastTriggerTime else {
continue
}
// 计算时间差(绝对值确保设备休眠后的正确性)
let elapsed = abs(currentDate.timeIntervalSince(lastTime))
if elapsed >= subscriber.interval {
// 主线程执行回调
DispatchQueue.main.async {
subscriber.handler(currentDate)
}
// 更新触发时间
subscriber.lastTriggerTime = currentDate
self.subscribers[uuid] = subscriber
}
}
}
}
private func unsubscribe(uuid: UUID) {
queue.async(flags: .barrier) { [weak self] in
self?.subscribers.removeValue(forKey: uuid)
}
}
}
// 使用示例
/**
// 启动定时器(App启动时调用)
GlobalTimerManager.shared.start()
// 在需要的地方订阅事件
class DataService {
private var cancellables = Set<AnyCancellable>()
init() {
// 订阅30秒间隔(不立即触发)
GlobalTimerManager.shared.subscribe(interval: 30) { [weak self] date in
self?.refreshData()
}.store(in: &cancellables)
}
private func refreshData() {
print("正在执行数据刷新...")
}
}
// 复杂间隔组合示例
class AnalyticsManager {
init() {
// 每分钟上报
GlobalTimerManager.shared.subscribe(interval: 60) { _ in
self.reportAnalytics()
}
// 每5秒检查一次网络状态
GlobalTimerManager.shared.subscribe(interval: 5) { _ in
self.checkNetworkStatus()
}
}
}
*/