Swift带返回值单次执行实现问题:OC单例转Swift
Swift 多线程安全单例与带返回值的单次执行方案
替代dispatch_once的核心逻辑
Swift 已弃用 dispatch_once,但语言层面提供了更简洁且线程安全的单次执行机制:静态存储属性(static let/var)的自动懒加载,系统会保证这类属性仅初始化一次,且多线程环境下安全。
1. 多线程安全单例实现(对应OC的dispatch_once单例)
这是Swift中最标准的单例写法,完全等价于OC中dispatch_once实现的线程安全单例:
class MySingleton { // 静态属性自动懒加载,系统保证线程安全,仅初始化一次 static let shared = MySingleton() // 私有初始化器,禁止外部通过 init() 创建实例 private init() { // 这里添加你的初始化逻辑 print("单例仅初始化一次") } // 示例业务方法 func performTask() { print("执行单例任务") } } // 使用方式 let instance = MySingleton.shared instance.performTask()
说明:
static let shared是懒加载的,只有第一次访问时才会执行初始化。- 系统原生保证该初始化过程的线程安全,无需手动加锁或调用
dispatch_once。 private init()确保外部无法创建新的实例,严格保证单例唯一性。
2. 通用带返回值的单次执行逻辑
如果需要更灵活的单次执行代码块(非单例场景),可以封装一个工具函数,利用静态属性的特性实现带返回值的单次执行:
// 通用单次执行函数,返回指定类型的结果,仅执行一次传入的代码块 func runOnce<T>(_ execute: () -> T) -> T { // 用结构体包裹静态属性,避免全局变量污染 struct ValueWrapper { static var cachedValue: T? } if let cached = ValueWrapper.cachedValue { return cached } let result = execute() ValueWrapper.cachedValue = result return result } // 使用示例 let uniqueResult = runOnce { print("这段代码仅执行一次") return "单次执行的返回结果" } print(uniqueResult) // 输出:单次执行的返回结果
说明:
- 结构体的静态属性
cachedValue同样由系统保证线程安全的初始化与访问。 - 代码块
execute仅在第一次调用runOnce时执行,后续调用直接返回缓存的结果。
初学者常见误区提醒
- 不要用实例级的
lazy var实现单例:实例级懒加载不保证线程安全,多线程下可能多次初始化。 - 无需手动加锁(如
NSLock、os_unfair_lock):静态属性的线程安全由Swift runtime原生保证,手动加锁反而容易引发死锁或性能问题。
内容的提问来源于stack exchange,提问作者charles bohica
相关产品推荐
相关产品推荐

