什么是單例模式?
單例模式是一種常用的軟件設(shè)計(jì)模式厢拭±加ⅲ可以保證通過(guò)單例模式可以保證系統(tǒng)中一個(gè)類只有一個(gè)實(shí)例而且該實(shí)例易于外界訪問(wèn),從而方便對(duì)實(shí)例個(gè)數(shù)的控制并節(jié)約系統(tǒng)資源供鸠。
為什么要使用單例模式畦贸?
如果我們希望在系統(tǒng)中某個(gè)類的對(duì)象只能存在一個(gè),單例模式是最好的解決方案。
怎么使用單例模式薄坏?
單例模式可以分為餓漢式
和懶漢式
,在iOS中我們經(jīng)常使用的是懶漢式
,下面我們看看怎么日常開(kāi)發(fā)中怎么運(yùn)用單例模式趋厉。
-
第一種寫(xiě)法:
+ (id)sharedInstance { static testClass *sharedInstance = nil; // 為了在多線程中也保證只產(chǎn)生一個(gè)實(shí)例,加上線程同步鎖 @synchronized(self) { if (!sharedInstance) { sharedInstance = [[self alloc] init]; } } return sharedInstance; }
-
第二種寫(xiě)法:
+ (instancetype)shareTools { return [[self alloc] init]; } + (instancetype)allocWithZone:(struct _NSZone *)zone { // 注意: 單例是不可以繼承的, 如果繼承引發(fā)問(wèn)題 // 如果先創(chuàng)建父類, 那么永遠(yuǎn)都是父類 // 如果先創(chuàng)建子類, 那么永遠(yuǎn)都是子類 static id instance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [super allocWithZone:zone]; }); return instance; }
注意:同時(shí)胶坠,我們還要重寫(xiě)copyWithZone君账,mutableCopyWithZone和非ARC的方法release,retain沈善,retainCount乡数。
抽取單例宏
由于單例模式在我們的日常開(kāi)發(fā)中使用頻率非常高,為了提高代碼的復(fù)用性闻牡,我們可以將單例模式的代碼抽取成一個(gè)宏净赴,這樣以后使用的時(shí)候可以用宏快速實(shí)現(xiàn)單例模式。
將下面的代碼寫(xiě)到Singleton.h文件中澈侠,以后用到單例的時(shí)候劫侧,直接將Singleton.h
添加到項(xiàng)目中即可快速實(shí)現(xiàn)單例。
使用方法:在要實(shí)現(xiàn)單例類的.h文件聲明中寫(xiě)下SingleInterface(*name*)
哨啃,.m文件中SingleImplementation(*name*)
烧栋,就實(shí)現(xiàn)了單例模式。
#define SingleInterface(name) +(instancetype)share##name
#if __has_feature(objc_arc)
// ARC
#define SingleImplementation(name) +(instancetype)share##name \
{ \
return [[self alloc] init]; \
} \
static id _instance; \
+ (instancetype)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [super allocWithZone:zone]; \
}); \
return _instance; \
} \
- (id)copyWithZone:(NSZone *)zone \
{ \
return self; \
} \
- (id)mutableCopyWithZone:(NSZone *)zone \
{ \
return self; \
}
#else
// MRC
#define SingleImplementation(name) +(instancetype)share##name \
{ \
return [[self alloc] init]; \
} \
static id _instance; \
+ (instancetype)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [super allocWithZone:zone]; \
}); \
return _instance; \
} \
- (id)copyWithZone:(NSZone *)zone \
{ \
return self; \
} \
- (id)mutableCopyWithZone:(NSZone *)zone \
{ \
return self; \
} \
- (oneway void)release \
{} \
- (instancetype)retain \
{ \
return self; \
} \
- (NSUInteger)retainCount \
{ \
return MAXFLOAT; \
}
#endif```