如何将dispatch_time_t转换为CFAbsoluteTime或struct timespec?
将 dispatch_time_t 转换为 CFAbsoluteTime 或 struct timespec
一、转换为 CFAbsoluteTime
dispatch_time_t 本质是基于 mach_absolute_time() 的64位整数,单位为Mach时间单位。要转成以秒为单位、基准为2001年1月1日00:00:00 UTC的CFAbsoluteTime,需先将Mach时间单位转换为秒,再关联到CFAbsoluteTime的时间轴。
代码示例:
#include <mach/mach_time.h> #include <CoreFoundation/CoreFoundation.h> #include <QuartzCore/QuartzCore.h> CFAbsoluteTime dispatch_time_to_cfabsolute(dispatch_time_t dt) { // 处理特殊值 if (dt == DISPATCH_TIME_NOW) { return CFAbsoluteTimeGetCurrent(); } if (dt == DISPATCH_TIME_FOREVER) { return INFINITY; // 可根据业务需求调整返回值 } // 缓存Mach时间转换因子,避免重复调用系统接口 static mach_timebase_info_data_t s_timebase_info; if (s_timebase_info.denom == 0) { mach_timebase_info(&s_timebase_info); } // 将dispatch_time_t转换为系统启动后的纳秒数,再转成秒 uint64_t mach_nanos = dt * s_timebase_info.numer / s_timebase_info.denom; double seconds_since_boot = mach_nanos / 1e9; // 计算系统启动时的CFAbsoluteTime,仅初始化一次 static double s_boot_absolute_time; static dispatch_once_t s_once_token; dispatch_once(&s_once_token, ^{ s_boot_absolute_time = CFAbsoluteTimeGetCurrent() - CACurrentMediaTime(); }); // 拼接得到最终的CFAbsoluteTime return s_boot_absolute_time + seconds_since_boot; }
二、转换为 struct timespec
struct timespec 包含秒(tv_sec)和纳秒(tv_nsec)两个字段,转换时需先将dispatch_time_t的Mach单位转换为纳秒,再拆分到对应字段中。
代码示例:
#include <mach/mach_time.h> #include <time.h> #include <stdint.h> bool dispatch_time_to_timespec(dispatch_time_t dt, struct timespec *out_ts) { if (out_ts == NULL) return false; // 处理特殊值 if (dt == DISPATCH_TIME_NOW) { clock_gettime(CLOCK_REALTIME, out_ts); return true; } if (dt == DISPATCH_TIME_FOREVER) { // 根据业务场景设置极大值或返回错误 out_ts->tv_sec = INT64_MAX; out_ts->tv_nsec = 999999999; return true; } // 缓存Mach时间转换因子 static mach_timebase_info_data_t s_timebase_info; if (s_timebase_info.denom == 0) { mach_timebase_info(&s_timebase_info); } // 转换为总纳秒数 uint64_t total_nanos = dt * s_timebase_info.numer / s_timebase_info.denom; // 拆分到timespec的秒和纳秒字段 out_ts->tv_sec = total_nanos / 1000000000; out_ts->tv_nsec = total_nanos % 1000000000; return true; }
注意事项
mach_timebase_info()返回的转换因子因设备而异,缓存后可减少系统调用开销。DISPATCH_TIME_FOREVER是一个极大值,转换时需根据业务需求定义处理逻辑。- 转换CFAbsoluteTime时,系统启动基准时间仅需计算一次,用
dispatch_once保证线程安全。
内容的提问来源于stack exchange,提问作者c00000fd
相关产品推荐
相关产品推荐

