前言
-
不推荐
直接使用:XXXClass *obj = [XXXClass [alloc] init];方式获取单例对象 - 建议直接使用shareInstance获取单例对象,这样跟官方统一
完整代码
static id _instance;// 全局的static的实例,直到程序退出才被销毁
/**
* 控制只分配一份内存空间,alloc方法会调用这个方法来分配内存
*/
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^ {
_instance = [super allocWithZone:zone];
});
return _instance;
}
/**
* 提供一个类方法供外界快速获取单例对象
*/
+ (instancetype)sharedInstance {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^ {
_instance = [[self alloc] init];
});
return _instance;
}
/**
* 控制拷贝对象也是同一个示例,可以不遵守<NSCopying>协议
*/
- (id)copyWithZone:(NSZone *)zone {
return _instance;
}
抽取成宏方便以后快速实现单例模式
- 将下面这段代码直接放到一个
头文件
中即可,什么地方使用直引用这个头文件就好了,这里假设头文件叫YHSingleton.h
// .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)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
著名的双锁技术实现单例
- 这里只重写allocWithZone:方法简单演示一下
- 使用@synchronized实现
// 著名的双锁技术
+(instancetype)allocWithZone:(struct _NSZone *)zone
{
if (_instance == nil)
{
@synchronized(self)
{
if(_instance == nil)
{
_instance = [super allocWithZone:zone];
}
}
}
return _instance;
}
- 使用锁对象(NSLock)实现
@implementation XXXClass
static NSLock *_lock;
+(void)initialize
{
//初始化锁对象
_lock = [[NSLock alloc]init];
}
// 著名的双锁技术
+(instancetype)allocWithZone:(struct _NSZone *)zone
{
if (_instance == nil)
{
// 加锁
[_lock lock];
if(_instance == nil)
{
_instance = [super allocWithZone:zone];
}
// 解锁
[_lock unlock];
}
return _instance;
}
网友评论