ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Objective-C学习 单例模式

2026/8/12 21:09:25 拓冰建站 浏览量
Objective-C学习 单例模式 文章目录单例模式的使用单例模式有两个关键点:单例要防止 3 种创建方式完整代码如下:单例模式的使用保证一个类在程序运行期间只创建一个对象并提供一个全局访问入口。单例模式有两个关键点:只能创建一个对象实例提供一个全局访问入口单例要防止 3 种创建方式alloccopymutablecopy单例模式需要实现一个公共访问的类方法一般命名为 shared 类名。在该方法的具体实现方案是推荐通过dispatch_once 来实现类的实例化。可以直接通过重写父类的方法把分配内存的方法变成只执行一次。从根本上实现了单例。单例模式主要需要重写三个方法 (instancetype) allocWithZone: (struct _NSZone*) zone - (id) copyWithZone: (NSZone*) zone - (id) mutableCopyWithZone: (NSZone*) zone在 Objective-C 中调用alloc方法时底层确实会直接调用allocWithZone:——alloc本质上是allocWithZone:的 “便捷封装”staticMyManager*_instance;(instancetype)sharedInstance{staticdispatch_once_t onceToken;dispatch_once(onceToken,^{_instance[[superallocWithZone:NULL]init];});return_instance;}static保存唯一对象, 用dispatch_once 保证只创建一次如果对象没有创建 – 创建如果对象已经创建 – 直接返回dispatch_once_t类型的onceToken本质是一个状态变量它存储着「代码块是否已经执行过」的信息初始状态onceToken是一个特殊的默认值可以理解为 “未执行”第一次执行dispatch_once时系统会把onceToken的值修改为 “已执行”并执行代码块后续执行dispatch_once时系统检测到onceToken已是 “已执行” 状态直接跳过代码块。instancetype是Objective-C里的一个返回类型关键字表示返回当前类的实例类型。它主要用于方法返回对象时让编译器更准确地知道返回的对象类型。为什么单例里要写[[super allocWithZone:NULL] init]而不是[[self alloc] init]这个其实是防止递归死循环在Objective-C的单例实现中我们通常会重写allocWithZone:。如果在sharedInstance里再调用[self alloc]就会触发这个重写的方法从而产生递归。调用 sharedInstance ↓[[selfalloc]init]↓ alloc ↓ allocWithZone ↓return[selfsharedInstance]↓ 再次进入 sharedInstance ↓[[selfalloc]init]↓ allocWithZone ↓...(instancetype)allocWithZone:(struct_NSZone*)zone{return[selfsharedInstance];}-(id)copyWithZone:(NSZone*)zone{return_instance;}-(id)mutableCopyWithZone:(NSZone*)zone{return_instance;}这段代码重写了allocWithZone:copyWithZone:mutableCopyZone:三种方法, 很好理解,直接返回唯一对象instance就可以了完整代码如下:implementationMyManagerstaticMyManager*_instance;(instancetype)sharedInstance{staticdispatch_once_t onceToken;dispatch_once(onceToken,^{_instance[[superallocWithZone:NULL]init];});return_instance;}(instancetype)allocWithZone:(struct_NSZone*)zone{return[selfsharedInstance];}-(id)copyWithZone:(NSZone*)zone{return_instance;}-(id)mutableCopyWithZone:(NSZone*)zone{return_instance;}end