單例模式

這篇文章的主要內(nèi)容包括:
1、在ARC中完成一個(gè)單例模式的三步
2、在MRC中完成一個(gè)單例模式的三步
3、單例模式通用宏(最重要)

單例模式是一種常用的軟件設(shè)計(jì)模式。
在它的核心結(jié)構(gòu)中只包含一個(gè)被稱(chēng)為單例的特殊類(lèi)。通過(guò)單例模式可以保證系統(tǒng)中一個(gè)類(lèi)只有一個(gè)實(shí)例,節(jié)約系統(tǒng)的資源。

  • 單例模式的應(yīng)用場(chǎng)景

在整個(gè)程序中,共享一份資源,這個(gè)資源只被初始化一次。

  • 在ARC中完成一個(gè)單例模式一共有三步:

0.提供靜態(tài)全局變量
1.重寫(xiě)allocWithZone
2.提供一個(gè)類(lèi)方法
3.重寫(xiě)copyWithZone和MutableCopyWithZone

#import "XMGTool.h"

@implementation XMGTool

//0.提供全局變量
static XMGTool *_instance;

//1.重寫(xiě)alloc方法
+(instancetype)allocWithZone:(struct _NSZone *)zone{

//    懶加載 永遠(yuǎn)只分配一次存儲(chǔ)空間
//    如果多個(gè)線(xiàn)程同時(shí)alloc,訪(fǎng)問(wèn)同一塊資源,可能涉及線(xiàn)程安全的問(wèn)題,所以我們可以加上一把互斥鎖
//    @synchronized (self) {
//        
//    }if(_instance==nil){
//        _instance=[super allocWithZone:zone];
//    }
//    方法二:GCD一次性代碼
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance=[super allocWithZone:zone];
    });

        return _instance;
}


//2.提供一個(gè)類(lèi)方法
//類(lèi)方法的好處在于:外界方便訪(fǎng)問(wèn);表明身份
//注意命名規(guī)范share+類(lèi)名/default+類(lèi)名
+(instancetype)shareTool{
    
    return [[self alloc]init];
    //這里alloc就調(diào)用了上面重寫(xiě)的alloc方法 保證只創(chuàng)建一個(gè)對(duì)象
    
}


//3.重寫(xiě)copy和mutable方法
-(id)copyWithZone:(NSZone *)zone{
    //對(duì)象方法,運(yùn)行之前已經(jīng)有對(duì)象存在了,所以直接返回就可以
    return _instance;
}

-(id)mutableCopyWithZone:(NSZone *)zone{
    return _instance;
}

@end

這樣,在控制器中不論用以下任何一種方式創(chuàng)建對(duì)象,地址都是相同的,因?yàn)橹粍?chuàng)建一次:

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    //1.重寫(xiě)allocWithZone
    //單例模式就是不管過(guò)程中alloc init多少次 new多少次 都始終是那一個(gè)對(duì)象
    //單例模式的實(shí)現(xiàn)方法:重寫(xiě)alloc方法
    XMGTool *t1=[[XMGTool alloc]init];
    XMGTool *t2=[[XMGTool alloc]init];
    XMGTool *t3=[XMGTool new];
    
    //2.提供一個(gè)類(lèi)方法
    XMGTool *t4=[XMGTool shareTool];
    
    //3.重寫(xiě)copyWithZone和MutableCopyWithZone
    //注意:這兩個(gè)方法都是對(duì)象方法
    XMGTool *t5=[t1 copy];
    XMGTool *t6=[t1 mutableCopy];

    
    NSLog(@"t1:%p----t2:%p----t3:%p----t4:%p----t5:%p----t6:%p",t1,t2,t3,t4,t5,t6);
}

  • 在MRC中實(shí)現(xiàn)單例模式也一共三步

非ARC模式事實(shí)上離我們已經(jīng)很遙遠(yuǎn)了
事實(shí)上,就是重寫(xiě)release和retain以及retainCount方法
這里可以使用一個(gè)小技巧 ——條件編譯(注意,條件編譯不可以用在宏中)
進(jìn)行判斷 如果不滿(mǎn)足ARC就執(zhí)行else和endif之間的

//上接ARC的三個(gè)方法
#if __has_feature(objc_arc)
#else
//MRC
-(oneway void)release{
    
}

-(instancetype)retain{
    return _instance;
}

//一個(gè)約定俗成的習(xí)慣
-(NSUInteger)retainCount{
    return MAXFLOAT;
}
#endif
  • 單例模式通用宏

其實(shí)以上兩個(gè)單例模式都不好
下面介紹在 ARC、MRC都可以實(shí)現(xiàn)單例模式的通用宏
用它實(shí)現(xiàn)代碼的復(fù)用,也就是說(shuō)把單例模式抽取出來(lái),以后用到的時(shí)候,在類(lèi)的h和m文件中包含這個(gè)宏就可以了

以下是宏中的代碼(條件判斷編譯不可以放在宏中):

 #define SingleH(name) +(instancetype)share##name;

#if __has_feature(objc_arc)
//ARC
#define SingleM(name) static id _instance;\
+(instancetype)allocWithZone:(struct _NSZone *)zone{\
    static dispatch_once_t onceToken;\
    dispatch_once(&onceToken, ^{\
        _instance=[super allocWithZone:zone];\
    });\
    return _instance;\
}\
+(instancetype)share##name{\
    return [[self alloc]init];\
    }\
-(id)copyWithZone:(NSZone *)zone{\
       return _instance;\
}\
-(id)mutableCopyWithZone:(NSZone *)zone{\
    return _instance;\
}



#else
//MRC
#define SingleM(name) static id _instance;\
+(instancetype)allocWithZone:(struct _NSZone *)zone{\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
_instance=[super allocWithZone:zone];\
});\
return _instance;\
}\
+(instancetype)share##name{\
return [[self alloc]init];\
}\
-(id)copyWithZone:(NSZone *)zone{\
return _instance;\
}\
-(id)mutableCopyWithZone:(NSZone *)zone{\
return _instance;\
}\
-(oneway void)release{\
}\
-(instancetype)retain{\
    return _instance;\
}\
-(NSUInteger)retainCount{\
    return MAXFLOAT;\
}

#endif


引用示例:


54D6E386-AE5D-4721-A6E1-B975F1D04F7D.png
C0BF99D7-831E-4905-A49E-5857374ED02F.png
E66A6E95-A367-4F03-A5DD-0D6E02180ECC.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,182評(píng)論 6 543
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,489評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,290評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,776評(píng)論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,510評(píng)論 6 412
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,866評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,860評(píng)論 3 447
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 43,036評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,585評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,331評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,536評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,058評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,754評(píng)論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,154評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,469評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,273評(píng)論 3 399
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,505評(píng)論 2 379

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

  • 單例模式的作用 可以保證在程序運(yùn)行過(guò)程,一個(gè)類(lèi)只有一個(gè)實(shí)例,而且該實(shí)例易于供外界訪(fǎng)問(wèn) 從而方便地控制了實(shí)例個(gè)數(shù),并...
    JonesCxy閱讀 385評(píng)論 0 0
  • 一. ARC環(huán)境下的單例模式 單例模式的基本概念單例, 顧名思義, 即在整個(gè)程序中, 某一個(gè)類(lèi)只有唯一一個(gè)實(shí)例, ...
    面糊閱讀 762評(píng)論 0 50
  • 近年來(lái)各種理論層出不窮,文章里不帶點(diǎn)“藍(lán)平長(zhǎng)二”之類(lèi)都不好意思讓人看。 為免(了)浪費(fèi)諸君的寶貴時(shí)間,特此對(duì)名詞做...
    SJTU_CTR閱讀 161評(píng)論 0 1
  • 周天奶奶給我買(mǎi)了一本優(yōu)秀作文選,我覺(jué)得這篇作文很好,在這里分享給大家。 作文的題目是《我會(huì)給動(dòng)畫(huà)配...
    徐雨恒閱讀 217評(píng)論 0 0
  • 今晚被同事嗆到哭,難受得無(wú)法自抑。 今天的狀態(tài)很差,繃緊了神經(jīng)辦理業(yè)務(wù)。旁邊一位同事在看考試題準(zhǔn)備周末統(tǒng)考,兩位在...
    素素_sky閱讀 378評(píng)論 0 0