单例(singleton)
实现单例模式有三个条件:
- 类的构造方法是私有的
- 类提供一个类方法用于产生对象
- 类中有一个私有的自己对象
针对于这三个条件,OC中都是可以做到的
- 类的构造方法是私有的
我们只需要重写allocWithZone方法,让初始化操作只执行一次 - 类提供一个类方法产生对象
这个可以直接定义一个类方法 - 类中有一个私有的自己对象
我们可以在.m文件中定义一个属性即可
- 可以保证在程序运行过程,一个类只有一个实例
- 应用场景
- 某个类经常被使用(节约系统资源)
- 定义工具类
- 共享数据
- 注意点
- 不要继承单例类
- 先创建子类永远是子类对象
- 先创建父类永远是父类对象
- 不要继承单例类
- 单例模式:
- 懒汉模式 : 第一次用到单例对象的时候再创建
- 饿汉模式 : 一进入程序就创建一个单例对象
ARC
懒汉模式
1 #import "Singleton.h" 2 3 @implementation Singleton 4 static id _instance; 5 6 /** 7 * alloc方法内部会调用这个方法 8 */ 9 + (instancetype)allocWithZone:(struct _NSZone *)zone{ 10 if (_instance == nil) { // 防止频繁加锁 11 @synchronized(self) { 12 if (_instance == nil) { // 防止创建多次 13 _instance = [super allocWithZone:zone]; 14 } 15 } 16 } 17 return _instance; 18 } 19 20 + (instancetype)sharedSingleton{ 21 if (_instance == nil) { // 防止频繁加锁 22 @synchronized(self) { 23 if (_instance == nil) { // 防止创建多次 24 _instance = [[self alloc] init]; 25 } 26 } 27 } 28 return _instance; 29 } 30 31 - (id)copyWithZone:(NSZone *)zone{ 32 return _instance; 33 } 34 @end
饿汉模式(不常用)
1 #import "HMSingleton.h" 2 3 @implementation Singleton 4 static id _instance; 5 6 /** 7 * 当类加载到OC运行时环境中(内存),就会调用一次(一个类只会加载1次) 8 */ 9 + (void)load{ 10 _instance = [[self alloc] init]; 11 } 12 13 + (instancetype)allocWithZone:(struct _NSZone *)zone{ 14 if (_instance == nil) { // 防止创建多次 15 _instance = [super allocWithZone:zone]; 16 } 17 return _instance; 18 } 19 20 + (instancetype)sharedSingleton{ 21 return _instance; 22 } 23 24 - (id)copyWithZone:(NSZone *)zone{ 25 return _instance; 26 } 27 @end
GCD实现单例模式
1 @implementation Singleton 2 static id _instance; 3 4 + (instancetype)allocWithZone:(struct _NSZone *)zone{ 5 static dispatch_once_t onceToken; 6 dispatch_once(&onceToken, ^{ 7 _instance = [super allocWithZone:zone]; 8 }); 9 return _instance; 10 } 11 12 + (instancetype)sharedSingleton{ 13 static dispatch_once_t onceToken; 14 dispatch_once(&onceToken, ^{ 15 _instance = [[self alloc] init]; 16 }); 17 return _instance; 18 } 19 20 - (id)copyWithZone:(NSZone *)zone{ 21 return _instance; 22 } 23 @end
非ARC
在非ARC的环境下,需要再加上下面的方法:
- 重写release方法为空
- 重写retain方法返回自己
- 重写retainCount返回1
- 重写autorelease返回自己
- (oneway void)release { }
- (id)retain { return self; }
- (NSUInteger)retainCount { return 1;}
- (id)autorelease { return self;}
- 如何判断是否是ARC
1 #if __has_feature(objc_arc) 2 3 //ARC环境 4 5 #else 6 7 //MRC环境 8 9 #endif
时间: 2024-11-08 21:04:43