聽說朋友去面試還要手寫一個單例呢?嗯,看來確實很重要!
- 下面說一下,2種我常用的寫法,事實上有好幾種寫法呢?
概念:保證一個類只有一個實例,并且提供一個訪問它的全局訪問點。
第一種方式:直接定義一個單例類?。。。⊿ingleon.h)
- 先看看結構目錄:

結構目錄.png
// .h
#define single_interface(class) + (class *)shared##class;
// .m
// \ 代表下一行也屬于宏
// ## 是分隔符
#define single_implementation(class) \
static class *_instance; \
\
+ (class *)shared##class \
{ \
if (_instance == nil) { \
_instance = [[self alloc] init]; \
} \
return _instance; \
} \
\
+ (id)allocWithZone:(NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [super allocWithZone:zone]; \
}); \
return _instance; \
}
- 然后,使用時,就是你要打算把誰當成單例去使用就OK啦!,下面用10秒讓你學會:
- 首先,導入剛才新建的 #import "Singleton.h"
-然后,新建一個例如:PersonManager的類,并且繼承NSObject在你想使用誰為單例的類里的 ".h" 文件里使用single_interface(PersonManager)

.h文件.png
-接著在,PersonManager的".m"文件里添加:

m文件.png
-最后,就是使用了!引入文件,然后:

使用.png
使用方式2:
同樣建立一個類繼承自NSObject
-在.h文件里寫上(最好單例以share、manager、sing等開頭) +(instancetype)shareSingleton;-
寫上這幾句(其實就是GCD的)
static DatabaseSingleton *single = nil;
static dispatch_once_t token = 0;+(instancetype)shareSingleton{ dispatch_once(&token, ^{ // 內容(最好這幾句代碼要會手寫!?。?,因為連面試都要手寫單例了) //single = [DatabaseSingleton new]; }); return single; }
懶加載的優(yōu)勢:
1:節(jié)約內存(用到才開辟)
2:不需要去思考實例化的位置
例如:
/** 游戲背景音樂 */
- (AVAudioPlayer *)gameBgMusic
{
if (_gameBgMusic == nil) {
_gameBgMusic = [[AVAudioPlayer alloc] initWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"主頁背景音樂.mp3" withExtension:nil] error:nil];
//-1 表示一直循環(huán)
_gameBgMusic.numberOfLoops = -1;
[_gameBgMusic prepareToPlay];
}
return _gameBgMusic;
}
下面是筆者在實際項目中使用的情景:

Snip20161009_1.png
實例化單例:

Snip20161009_3.png
使用非常的方便:直接調用。

Snip20161009_4.png
總結:
- 1、在程序運行過程,一個類只有一個實例,無論如何程序運行過程中只有一份實例。實現(xiàn)每次調用都是同一份資源;
- 2、上圖可以看出,不使用單例,如果多個類都要使用這個音頻的話,那么就要創(chuàng)建很多實例,開銷大,浪費資源等。