饿汉式其实就是当程序一启动就是创建单例,在ios中不推荐去使用
static id instance;
+ (void)load //装载内存时就实例化,仅此一次
{
_instance = [[self alloc] init];
}
+ (id)allocWithZone:(struct _NSZone *)zone
{
//这里可以不用加锁,因为是在load里面创建的
if (_instance == nil) { // 防止创建多次
_instance = [super allocWithZone:zone];
}
return _instance;
}
+ (instancetype)sharedManagerTool
{
return _instance;
}
- (id)copyWithZone:(NSZone *)zone
{
return _instance;
}
GCD的单例实现方式
static id _instace;
+ (id)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
//这个函数是线程安全的
dispatch_once(&onceToken, ^{
_instace = [super allocWithZone:zone];
});
return _instace;
}
+ (instancetype)sharedDataTool
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [[self alloc] init];
});
return _instace;
}
- (id)copyWithZone:(NSZone *)zone
{
return _instace;
}
懒汉式的实现就是在用到的时候再去创建
static id _instance;
//alloc内部会调用这个代码
+ (id)allocWithZone:(struct _NSZone *)zone
{
if (_instance == nil) { // 防止频繁加锁
@synchronized(self) {
if (_instance == nil) { // 防止创建多次
_instance = [super allocWithZone:zone];
}
}
}
return _instance;
}
+ (instancetype)sharedMusicTool
{
if (_instance == nil) { // 防止频繁加锁
@synchronized(self) {
if (_instance == nil) { // 防止创建多次
_instance = [[self alloc] init];
}
}
}
return _instance;
}
- (id)copyWithZone:(NSZone *)zone
{
return _instance;
}
非ARC下的单例模式
static id _instace;
+ (id)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [super allocWithZone:zone];
});
return _instace;
}
+ (instancetype)sharedDataTool
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [[self alloc] init];
});
return _instace;
}
- (id)copyWithZone:(NSZone *)zone
{
return _instace;
}
//为了保证对象不被释放,所以在release中不做任何操作
-(oneway void)release
{
}
//retain的时候返回自己
- (id)retain
{
return self;
}
- (NSUInteger)retainCount
{
return 1;
}
//这里其实加不加都一样,因为最后会调用release操作,而我们又重写了release方法
- (id)autorelease {
return self;
}
因为我们如果每用到一个类就要去复制这些代码,所以我们可以把这些代码定义成宏,确定就是不好调试。\这个的意思就是后面的一行都是它的.我们想用的话想把sharedInstance的Instance的名字改成我们自己传的名字,下面加()和传入参数name
// .h文件
#define SingletonH(name) + (instancetype)shared##name;
// .m文件
#define SingletonM(name) \
static id _instance; \
\
+ (id)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; \
} \
\
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instance; \
}
我们在写项目的时候如果想要指定在ARC下执行什么代码,在MRC下执行什么代码,我们可以用条件编译来写
#if __has_feature(objc_arc)
//编译环境是ARC
NSLog(@"kkk");
#else
//编译环境是MRC
NSLog(@"kkk");
#endif