M1设备下DispatchTime使用异常与相关测试失败问题咨询
结论
测试用例的设计存在问题,不符合DispatchTime的官方使用约定,并非Combine或Dispatch框架的缺陷。
原因说明
极小时间值的构造不符合接口预期
官方文档明确标注DispatchTime(uptimeNanoseconds: 0)等价于DispatchTime.now(),所有传入的uptimeNanoseconds如果小于当前设备从启动到运行测试时累计的纳秒数,都会被静默修正为当前时间。你测试中传入的10000、10431这类极小值,远低于设备正常启动后到测试运行的耗时,构造出的time1、time2本质上都是测试运行时的当前时间,自然无法得到预期的差值。M1架构的时间对齐机制差异
Intel平台的Mach时间基准和纳秒是1:1对应,你传入的任意纳秒值都不会被修正;但M1平台的时间基准以12纳秒为最小单位,所有传入的uptimeNanoseconds都会被向上取整为12的倍数,比如10000会被修正为10008、10431会被修正为10440,两者差值并非你预期的431,直接导致断言失败。distantFuture的使用方式错误DispatchTime.distantFuture是系统预定义的固定极大值,设计用途是表示“永远不会触发的时间点”,并非用于算术运算的相对值。你用它减去1024构造出的时间点,同样远小于当前系统运行的累计纳秒数,也会被修正为当前时间,相关差值计算逻辑从根本上不符合接口设计规则。
修复方案
- 所有测试用的时间点都基于当前时间偏移构造,不要手动传入固定的极小
uptimeNanoseconds值,示例如下:
let now = DispatchTime.now() let time1 = DispatchQueue.SchedulerTimeType(now) let time2 = DispatchQueue.SchedulerTimeType(now + .nanoseconds(431))
这类构造方式完全符合DispatchTime的使用规范,跨架构不会出现对齐问题,差值计算结果和预期一致。
- 针对
distantFuture的测试仅验证两个distantFuture实例的差值为0即可,不要手动修改其uptimeNanoseconds属性做算术运算。 - 如果需要测试原始纳秒值的计算逻辑,单独抽离相关逻辑做单元测试,不要和系统
DispatchTime的实现耦合。
内容的提问来源于stack exchange,提问作者Bobj-C

