iOS OperationQueue.schedule不受系统修改日期影响的实现方案咨询
解决方案
你需要的功能iOS系统有原生API支持,无需自行轮询KERN_BOOTTIME实现。核心是使用以系统内核绝对时间为基准的调度API,而非依赖用户可修改的日历时间。
最优实现方案
使用DispatchQueue或OperationQueue的调度方法时,传入基于DispatchTime的时间参数即可,该时间参数的基准是设备本次启动的时刻,和用户在设置中修改的系统日期完全独立,且锁屏休眠时也会正常累计计时,完全满足你的需求:
// 示例:延迟60秒触发回调,不受系统日期修改影响 let triggerDelay: TimeInterval = 60 let triggerTime = DispatchTime.now() + triggerDelay // 方案1:用GCD触发 DispatchQueue.main.asyncAfter(deadline: triggerTime) { print("回调正常触发,无法通过回退系统日期提前调用") } // 方案2:用OperationQueue触发 OperationQueue.current?.schedule(after: triggerTime) { print("OperationQueue回调触发,不受系统日期修改影响") }
原理说明
DispatchTime底层基于mach_absolute_time实现,和KERN_BOOTTIME是同源时间基准,本身和用户设置的日历时间完全隔离,修改系统日期不会对该时间的计算产生任何影响,从根源避免了用户绕过时序限制的可能。- 系统底层会直接维护该类型的调度任务,到点自动触发,无需你自行实现计时器轮询校验启动时间。
注意事项
不要使用asyncAfter(wallDeadline:)接口,该接口传入的是挂钟时间(和Date同源),修改系统日期会影响触发时机。
内容的提问来源于stack exchange,提问作者Richard Topchii
相关产品推荐
相关产品推荐

