从实例到单例:Objective-C 单例类的线程安全实现方案

从实例到单例:Objective-C 单例类的线程安全实现方案

在 Objective-C 中实现线程安全的单例模式需解决两个核心问题:

  1. 确保全局唯一实例
  2. 防止多线程环境下的竞态条件
一、基础实现方案
objectivec 复制代码
// MySingleton.h
@interface MySingleton : NSObject
+ (instancetype)sharedInstance;
@end

// MySingleton.m
@implementation MySingleton
+ (instancetype)sharedInstance {
    static MySingleton *_sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedInstance = [[self alloc] init];
    });
    return _sharedInstance;
}
@end

关键组件:

  • static 变量保证实例生命周期与程序相同
  • dispatch_once_t 确保代码块仅执行一次
  • GCD 的 dispatch_once 提供原子性操作
二、线程安全分析

设 T_1, T_2 为并发线程,其执行过程满足: P(T_1 \\cap T_2) = \\emptyset \\implies \\text{单例唯一性} dispatch_once 的底层实现基于:

  1. 原子性内存屏障
  2. 信号量锁机制
  3. 双重检查锁定模式
三、防御性改进方案

防止通过其他方式创建实例:

objectivec 复制代码
// 重写 allocWithZone 方法
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    return [self sharedInstance];
}

// 防止拷贝
- (id)copyWithZone:(NSZone *)zone {
    return self;
}
四、性能对比
实现方案 线程安全 时间复杂度 内存屏障
@synchronized 是 O(n) 有
dispatch_once 是 O(1) 无
双重检查锁定 否 O(1) 无

最佳实践:

  1. 始终使用 dispatch_once 方案
  2. 在 .m 文件中声明静态变量而非头文件
  3. 重写 allocWithZone: 和 copyWithZone: 方法
  4. 避免在单例初始化方法中调用 sharedInstance
五、使用场景

适合以下全局服务:

  • 配置管理器
  • 网络监控器
  • 核心数据栈
  • 日志系统
graph LR A[调用 sharedInstance] --> B{实例是否存在?} B -- 否 --> C[dispatch_once 创建] B -- 是 --> D[返回现存实例] C --> D

此方案满足: \\forall t \\in \\mathbb{T}, \\quad \\exists! , \\text{instance} \\in \\text{MySingleton} 其中 \\mathbb{T} 表示线程集合,\\exists! 表示存在且唯一。

相关推荐
sunshine22 girl17 分钟前
Java学习六 Java常见API-2--String-3-字符串的截取替换和其他方法
java·开发语言·学习
LOVE️YOU27 分钟前
Python 函数名、函数对象与“把函数作为参数传递”
开发语言·python
sunshine22 girl1 小时前
Java学习六 Java常见API-1-Radom随机数
java·开发语言·学习
可乐鸡翅yeah_1 小时前
hls.js 手动自定义 http 请求 loader,修改请求头实战
开发语言·前端·javascript·网络协议·http·ecmascript·m3u8在线
潼心1412o1 小时前
C++初阶(长期更新)第6讲:类和对象(下)
开发语言·c++·算法
夜晚回家2 小时前
Python 零基础入门 | 输入的数字为什么不能直接算
开发语言·python
时间的拾荒人2 小时前
Qt 事件机制全解析:从事件处理到事件过滤器
开发语言·qt·面试
于指尖飞舞2 小时前
java面试题总结
java·开发语言
zhangzeyuaaa3 小时前
深入理解 Ruby 运算符:本质、分类、坑点与重载实战
开发语言·前端·ruby
一木 之林3 小时前
DeepSeek Agent 开发(一)
开发语言·前端·javascript