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

Swift中如何为协议实现者自动分配唯一静态ID?

解决方案

要实现让所有遵循IdProtocol的类型自动获得唯一且懒加载的静态id,可以通过全局计数器+类型标识字典的方式来实现,具体代码如下:

核心实现代码

protocol IdProtocol {
    static var id: Int { get }
}

// 私有全局变量:用于分配id的计数器和存储已分配id的字典
private var idCounter = 0
private var typeIds: [ObjectIdentifier: Int] = [:]
// 可选:多线程环境下加锁保证线程安全
private let idLock = NSLock()

extension IdProtocol {
    static var id: Int {
        let typeIdentifier = ObjectIdentifier(Self.self)
        
        // 加锁避免多线程竞争(如果不需要线程安全可以去掉锁相关代码)
        idLock.lock()
        defer { idLock.unlock() }
        
        // 懒加载逻辑:如果类型未分配过id则分配并存储,否则直接返回已有的id
        if let existingId = typeIds[typeIdentifier] {
            return existingId
        }
        let newId = idCounter
        idCounter += 1
        typeIds[typeIdentifier] = newId
        return newId
    }
}

测试示例

struct One: IdProtocol {}
struct Two: IdProtocol {}

print(One.id) // 输出 0
print(Two.id) // 输出 1
print(One.id) // 再次访问仍输出 0,验证懒加载特性

原理说明

  1. 类型标识:用ObjectIdentifier(Self.self)获取每个遵循协议类型的唯一标识,作为字典的key;
  2. 懒加载分配:第一次访问static var id时,检查字典中是否已有该类型的id,没有则用全局计数器分配新值,并存入字典;
  3. 线程安全:如果你的代码会在多线程环境下访问id,加上NSLock可以避免多个线程同时分配id导致的重复问题;
  4. 自动实现:所有遵循IdProtocol的类型无需额外编写id的实现,直接继承扩展中的逻辑即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 17:51:30