iOS中的單例設(shè)計(jì)模式

什么是單例模式?

單例模式是一種常用的軟件設(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```
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拳球,一起剝皮案震驚了整個(gè)濱河市审姓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌祝峻,老刑警劉巖魔吐,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異莱找,居然都是意外死亡酬姆,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門奥溺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)辞色,“玉大人,你說(shuō)我怎么就攤上這事浮定∠嗦” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵桦卒,是天一觀的道長(zhǎng)立美。 經(jīng)常有香客問(wèn)我,道長(zhǎng)方灾,這世上最難降的妖魔是什么建蹄? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上躲撰,老公的妹妹穿的比我還像新娘针贬。我一直安慰自己,他們只是感情好拢蛋,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布桦他。 她就那樣靜靜地躺著,像睡著了一般谆棱。 火紅的嫁衣襯著肌膚如雪快压。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,679評(píng)論 1 305
  • 那天垃瞧,我揣著相機(jī)與錄音蔫劣,去河邊找鬼。 笑死个从,一個(gè)胖子當(dāng)著我的面吹牛脉幢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嗦锐,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼嫌松,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了奕污?” 一聲冷哼從身側(cè)響起萎羔,我...
    開(kāi)封第一講書(shū)人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎碳默,沒(méi)想到半個(gè)月后贾陷,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嘱根,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年髓废,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片该抒。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡慌洪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出柔逼,到底是詐尸還是另有隱情,我是刑警寧澤割岛,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布愉适,位于F島的核電站,受9級(jí)特大地震影響癣漆,放射性物質(zhì)發(fā)生泄漏维咸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望癌蓖。 院中可真熱鬧瞬哼,春花似錦、人聲如沸租副。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)用僧。三九已至结胀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間责循,已是汗流浹背糟港。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留院仿,地道東北人秸抚。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像歹垫,于是被迫代替她去往敵國(guó)和親剥汤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 單例:意思就是只有一個(gè)實(shí)例县钥。單例模式確保某一個(gè)類只有一個(gè)實(shí)例秀姐,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例。這個(gè)類稱為單...
    CoderZS閱讀 605評(píng)論 1 13
  • 在開(kāi)發(fā)中經(jīng)常會(huì)用到單例設(shè)計(jì)模式若贮,目的就是為了在程序的整個(gè)生命周期內(nèi)省有,只會(huì)創(chuàng)建一個(gè)類的實(shí)例對(duì)象,而且只要程序不被殺死...
    不要重名就好閱讀 548評(píng)論 0 0
  • 在開(kāi)發(fā)中經(jīng)常會(huì)用到單例設(shè)計(jì)模式谴麦,目的就是為了在程序的整個(gè)生命周期內(nèi)蠢沿,只會(huì)創(chuàng)建一個(gè)類的實(shí)例對(duì)象,而且只要程序不被殺死...
    VincentHK閱讀 651評(píng)論 0 3
  • -1- 講真,我一點(diǎn)都不想來(lái)學(xué)校面哼,為什么呢野宜?因?yàn)槿思掖笏牧耍趺淳痛笏牧耍?我還不能接受這個(gè)現(xiàn)實(shí)魔策,仿佛昨天我還抱著...
    愛(ài)上世界的張大路閱讀 537評(píng)論 4 17
  • 片段一: 選自《堅(jiān)持匈子,一種可以養(yǎng)成的習(xí)慣》 R-原文片段 盡量找出不被侵犯的“圣地” 利用不容易被工作或私事影響的...
    笑語(yǔ)盈盈_8635閱讀 217評(píng)論 0 0