單例模式
單例的目的:希望對象只創(chuàng)建一個(gè)單例,并且提供一個(gè)全局的訪問點(diǎn)
單例模式(arc)
+(instancetype)sharedTools;
類的實(shí)現(xiàn)
//定義一個(gè)靜態(tài)成員,報(bào)訊唯一的實(shí)例
static id instance;
//保證對象只被分配一次內(nèi)存空間,通過dispatch_once能夠保證單例的分配和初始化時(shí)線程安全的
-(instancetype)init{
? ? ?self = [super init];
? ? ? if(self){
? ? ? ? ? ? ?//對對象屬性的初始化
? ? ? ? ? ? }
? ? ? ? ? return self;
}
//申請內(nèi)存空間
+(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;
}
//實(shí)現(xiàn)copy的時(shí)候調(diào)用單例
-(id)copyWithZone:(NSZone*)zone{
? ? ? return instance匆帚;
}
一般開發(fā)開發(fā)中只需要寫sharedTools,當(dāng)我們自已調(diào)用的時(shí)候只需要調(diào)用這個(gè)接口就行
我們可以把上邊的代碼抽取出來一個(gè)單例宏只需要我們引入這個(gè)頭文件即可簡單的實(shí)現(xiàn)單例
// 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中吸重,標(biāo)準(zhǔn)只定義了#和##兩種操作。#用來把參數(shù)轉(zhuǎn)換成字符串歪今,##則用來連接兩個(gè)前后兩個(gè)參數(shù)嚎幸,把它們變成一個(gè)字符串。
#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