单例模式
单例的目的:希望对象只创建一个单例,并且提供一个全局的访问点
单例模式(arc)
+(instancetype)sharedTools;
类的实现
//定义一个静态成员,报讯唯一的实例
static id instance;
//保证对象只被分配一次内存空间,通过dispatch_once能够保证单例的分配和初始化时线程安全的
-(instancetype)init{
self = [super init];
if(self){
//对对象属性的初始化
}
return self;
}
//申请内存空间
+(instancetype)allocWithZone:(struct _NSZone*)zone{
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
instance = [super allocWithZone:zone];
});
return instance;
}
//保证对象只被初始化一次
+(instancetype)sharedTools{
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
instance = [[self alloc]init];
});
return instance;
}
//实现copy的时候调用单例
-(id)copyWithZone:(NSZone*)zone{
return instance;
}
一般开发开发中只需要写sharedTools,当我们自已调用的时候只需要调用这个接口就行
我们可以把上边的代码抽取出来一个单例宏只需要我们引入这个头文件即可简单的实现单例
// 1. 解决.h文件
#define singletonInterface(className) +(instancetype)shared##className;
// 2. 解决.m文件
// 判断 是否是 ARC
#if __has_feature(objc_arc)
#define singletonImplementation(className) \
staticidinstance; \
+ (instancetype)allocWithZone:(struct_NSZone*)zone { \
staticdispatch_once_tonceToken; \
dispatch_once(&onceToken, ^{ \
instance = [superallocWithZone:zone]; \
}); \returninstance; \
} \
+ (instancetype)shared##className { \
staticdispatch_once_tonceToken; \
dispatch_once(&onceToken, ^{ \
instance = [[selfalloc] init]; \
}); \
returninstance; \
} \
- (id)copyWithZone:(NSZone*)zone { \
returninstance; \
}#else
// MRC 部分
#define singletonImplementation(className) \
staticidinstance; \
+ (instancetype)allocWithZone:(struct_NSZone*)zone { \
staticdispatch_once_tonceToken; \
dispatch_once(&onceToken, ^{ \
instance = [superallocWithZone:zone]; \
}); \
returninstance; \
} \
+ (instancetype)shared##className { \
staticdispatch_once_tonceToken; \
dispatch_once(&onceToken, ^{ \
instance = [[selfalloc] init]; \
}); \
returninstance; \
} \
- (id)copyWithZone:(NSZone*)zone { \
returninstance; \
} \
- (onewayvoid)release {} \
- (instancetype)retain {returninstance;} \
- (instancetype)autorelease {returninstance;} \
- (NSUInteger)retainCount {returnULONG_MAX;}
#endif
// 提示,最后一行不要使用 \
注意:
在#define中,标准只定义了#和##两种操作。#用来把参数转换成字符串,##则用来连接两个前后两个参数,把它们变成一个字符串。
#include
#definepaster( n ) printf( "token " #n" = %d\n ", token##n )
int main()
{
int token9=10;
paster(9);
return 0;
}
输出为
[leshy@leshy src]$ ./a.out
token 9 = 10