抽取成宏方便以后快速实现单例模式
使用前提:没有自定义的初始化代码
如果有初始化代码,可以将这段封装成代码片段方便以后使用
宏抽取,将下面这段直接放到一个头文件中即可,什么地方使用直引用这个头文件就好了
// .h文件 #define YHSingletonH(name) + (instancetype)shared##name; // .m文件 #define YHSingletonM(name) \ /** * 全局的static的实例,直到程序退出才被销毁 * 使用static可以让外界不能访问_instance全局变量 */\ static id _instance;\ \ /** * 控制只分配一份内存空间 */\ +(instancetype)allocWithZone:(struct _NSZone *)zone\ {\ static dispatch_once_t onceToken;\ dispatch_once(&onceToken, ^\ {\ _instance = [super allocWithZone:zone];\ });\ \ return _instance;\ }\ \ /** * 控制只初始化一次,无自定义初始化代码才能使用此宏 */\ -(instancetype)init\ {\ __block typeof(self) onceSelf = self;\ static dispatch_once_t onceToken;\ dispatch_once(&onceToken, ^\ {\ onceSelf = [super init];\ });\ \ return onceSelf;\ }\ \ /** * 提供一个类方法供外界快速获取单例对象 */\ +(instancetype)shared##name\ {\ static dispatch_once_t onceToken;\ dispatch_once(&onceToken, ^\ {\ _instance = [[self alloc] init];\ });\ return _instance;\ }\ \ /** * 控制拷贝对象也是同一个示例,可以不遵守<NSCopying>协议 */\ -(id)copyWithZone:(NSZone *)zone\ {\ return _instance;\ }\ |
使用示例
在.h文件
#import <Foundation/Foundation.h> // 引入宏定义头文件 #import "YHSingleton.h" @interface YHXXX : NSObject /** 名字 */ @property (nonatomic, strong) NSString *name; /** .h文件中使用YHSingletonH方法 */ YHSingletonH(XXX) @end 在.m文件 #import "YHXXX.h" @interface YHXXX() @end @implementation YHXXX /** .m文件中使用YHSingletonM方法实现单例 */ YHSingletonM(XXX) @end 单例模式不适合使用继承实现的原因 static id _instance;在整个内存中只有一份,所以会导致一下错误,用代码说明一下: // 比如有一个基类 YHSingelton // YHPerson继承于YHSingelton YHPerson : YHSingelton // YHCar也继承于YHSingelton YHCar : YHSingelton // 打印出来的都是YHPerson对象 // 因为static id _instance;在整个内存中只有一份 NSLog(@"%@---%@", [YHPerson sharedInstance], [[YHCar sharedInstance]); 也可以通过互斥锁的方式实现单例模式,但是没有必要,用GCD就很好了,这里只重写allocWithZone:方法简单演示一下 // 著名的双锁技术 + (instancetype)allocWithZone:(struct _NSZone *)zone { if (_instance == nil) { @synchronized(self) { if(_instance == nil) { _instance = [super allocWithZone:zone]; } } } return _instance; } |