使用NSDate timeIntervalSinceNow获取耗时数值异常问题排查
问题解析与解决方案
为什么NSDate计时会出现几千秒的异常值?
这是NSDate的本质特性导致的:
NSDate依赖的是系统墙钟时间(即设备设置里的真实时间),如果在异步调用执行过程中,系统时间被手动修改、NTP自动校准,甚至时区切换,都会让[start timeIntervalSinceNow]的计算结果完全失真。比如系统时间被往后调了1小时,算出来的耗时就会凭空多出3600秒,这就是你看到异常大数值的原因。- 而
CACurrentMediaTime()是基于设备启动后的累计运行时间,完全不受系统墙钟时间变动的影响,所以能精准反映任务的实际耗时。
你的NSDate代码还有语法错误
原代码里的调用写法存在语法问题,缺少参数括号和方法调用的冒号:
// 错误写法 [recordMetricWithDuration fabs([start timeIntervalSinceNow]];
正确的调用应该是(假设recordMetricWithDuration:是接收时长的实例方法):
// 修正后 [self recordMetricWithDuration:fabs([start timeIntervalSinceNow])];
但就算修正了语法,只要系统时间变动,还是会出现异常值,这是NSDate作为计时工具的天生缺陷。
NSTimeInterval和CFTimeInterval的类型问题
这个完全不用担心:NSTimeInterval和CFTimeInterval都是double类型的别名,两者完全等价,互相传递不会有任何类型问题,这不是导致异常的原因。
最终结论
统计异步任务的耗时,优先用CACurrentMediaTime(),它能提供稳定、准确的计时结果;如果非要用NSDate,只能在确保系统时钟绝对不会变动的场景下使用,但这在用户设备上根本无法保证,所以不推荐。
内容的提问来源于stack exchange,提问作者Dracula
相关产品推荐
相关产品推荐

