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,验证懒加载特性
原理说明
- 类型标识:用
ObjectIdentifier(Self.self)获取每个遵循协议类型的唯一标识,作为字典的key; - 懒加载分配:第一次访问
static var id时,检查字典中是否已有该类型的id,没有则用全局计数器分配新值,并存入字典; - 线程安全:如果你的代码会在多线程环境下访问
id,加上NSLock可以避免多个线程同时分配id导致的重复问题; - 自动实现:所有遵循
IdProtocol的类型无需额外编写id的实现,直接继承扩展中的逻辑即可。
内容的提问来源于stack exchange,提问作者Jomy
相关产品推荐
相关产品推荐

