You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让CMTime在所有iOS版本中遵循Hashable协议?

全iOS版本兼容CMTime/CMTimeRange的Hashable一致性解决方案

问题背景

Xcode 14中,苹果仅为iOS 16及以上版本的CMTime和CMTimeRange添加了Hashable协议一致性。若项目中存在大量包含CMTime的Hashable结构体,且需要兼容低版本iOS,会遇到编译报错或兼容性问题。


方案一:带版本控制的Hashable扩展(推荐)

你提到的实现hashValue的方案是安全可行的,只需补充版本标记和完整的协议实现即可解决编译问题,且无需修改现有业务代码。

完整代码实现

import CoreMedia

// 为CMTime添加Hashable兼容,覆盖iOS 16以下版本
@available(iOS, introduced: 8.0, deprecated: 16.0, message: "iOS 16+ 已提供原生Hashable一致性")
extension CMTime: Hashable, Equatable {
    public static func == (lhs: CMTime, rhs: CMTime) -> Bool {
        // 复用系统的相等判断逻辑
        return CMTimeEqualToTime(lhs, rhs)
    }
    
    public func hash(into hasher: inout Hasher) {
        // 根据CMTime核心字段生成哈希值,对齐iOS 16+原生实现逻辑
        hasher.combine(value)
        hasher.combine(timescale)
        hasher.combine(flags)
        hasher.combine(epoch)
    }
    
    @available(iOS, deprecated: 16.0, message: "推荐使用hash(into:)替代")
    public var hashValue: Int {
        var hasher = Hasher()
        hash(into: &hasher)
        return hasher.finalize()
    }
}

// 同理处理CMTimeRange
@available(iOS, introduced: 8.0, deprecated: 16.0, message: "iOS 16+ 已提供原生Hashable一致性")
extension CMTimeRange: Hashable, Equatable {
    public static func == (lhs: CMTimeRange, rhs: CMTimeRange) -> Bool {
        return CMTimeRangeEqualToTimeRange(lhs, rhs)
    }
    
    public func hash(into hasher: inout Hasher) {
        hasher.combine(start)
        hasher.combine(duration)
    }
    
    @available(iOS, deprecated: 16.0, message: "推荐使用hash(into:)替代")
    public var hashValue: Int {
        var hasher = Hasher()
        hash(into: &hasher)
        return hasher.finalize()
    }
}

方案安全性说明

  1. hashValue弃用不影响功能:hashValue的弃用只是Swift API演进的提示,并非功能移除,在低版本iOS中依然能正常工作。
  2. 哈希一致性保障:hashValue完全基于hash(into:)生成,保证同一CMTime在不同版本系统中生成的哈希值一致。
  3. 版本隔离避免冲突:通过@available标记,iOS 16+系统会优先使用原生的Hashable实现,我们的扩展仅在低版本生效,不会产生冲突。
  4. 编译报错解决:给hashValue添加弃用标记后,编译器会认可其可用性覆盖范围,不再抛出“requires 'hashValue' to be available”的错误。

方案二:封装Hashable容器(不推荐)

你提到的封装Hashed结构体的方案虽然可行,但需要修改所有包含CMTime的Hashable结构体的hash(into:)实现,改动范围大、维护成本高,仅在无法使用方案一的极端场景下考虑。


内容的提问来源于stack exchange,提问作者Guy Niv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 10:15:35