iOS 單例中dispatch_once的原理

先來(lái)段代碼:

+ (instancetype)shareInstance{
    static BETestSingleton * single;
    static dispatch_once_t onceToken;
    NSLog(@"====>%ld",onceToken);    
    dispatch_once(&onceToken, ^{
        NSLog(@"====>block內(nèi):%ld",onceToken);
        single = [[BETestSingleton alloc] init];
    });
    NSLog(@"======>block外:%ld",onceToken);
    return single;
}

這是利用dispatch_once實(shí)現(xiàn)單例的方式,運(yùn)行看看會(huì)輸出什么:

====>0
====>block內(nèi):768
======>block外:-1

生成完單例對(duì)象后,在其他地方調(diào)用單例:

NSString *testStr = [BETestSingleton shareInstance].testString;

會(huì)輸出:

====>-1
======>block外:-1

下面來(lái)看一下為什么這么輸出以及dispatch_once的原理:

dispatch_once主要是根據(jù)onceToken的值來(lái)決定怎么去執(zhí)行代碼。

1.當(dāng)onceToken= 0時(shí),線程執(zhí)行dispatch_once的block中代碼

2.當(dāng)onceToken= -1時(shí),線程跳過(guò)dispatch_once的block中代碼不執(zhí)行

3.當(dāng)onceToken為其他值時(shí),線程被阻塞,等待onceToken值改變

當(dāng)線程調(diào)用shareInstance,此時(shí)onceToken= 0,調(diào)用block中的代碼,此時(shí)onceToken的值變?yōu)?68。當(dāng)其他線程再調(diào)用shareInstance方法時(shí),onceToken的值已經(jīng)是768了,線程阻塞。當(dāng)block線程執(zhí)行完block之后,onceToken變?yōu)?1.其他線程不再阻塞,跳過(guò)block。下次再調(diào)用shareInstance時(shí),block已經(jīng)為-1.直接跳過(guò)block。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 單例介紹 本文源碼下載地址 1.什么是單例 說(shuō)到單例首先要提到單例模式,因?yàn)閱卫J绞菃卫嬖诘哪康?單例模式是一...
    雷鳴1010閱讀 3,538評(píng)論 0 19
  • 在開發(fā)中使用單例是最經(jīng)常不過(guò)的事兒了,最常用的就是dispatch_once這個(gè)函數(shù),這個(gè)函數(shù)可以使其參數(shù)內(nèi)的bl...
    ilovehusky閱讀 13,242評(píng)論 8 52
  • 經(jīng)常用到單例,但也僅僅是停留在會(huì)用的層次,至于為什么這么用,內(nèi)部怎么實(shí)現(xiàn)的,從未研究過(guò)。在面試的時(shí)候,被問(wèn)到了單例...
    YSL一路行走閱讀 2,610評(píng)論 5 29
  • 前言 單例應(yīng)該是iOS中很簡(jiǎn)單的設(shè)計(jì)模式,寫個(gè)單例很簡(jiǎn)單很方便。網(wǎng)上例子也很多,大家也是基本上copy下來(lái)就可以了...
    楓葉無(wú)處漂泊閱讀 5,774評(píng)論 0 12
  • 一、為什么需要session共享 HttpSession是由servelet容器進(jìn)行管理的。而我們常用的應(yīng)用容器有...
    夏日橘子冰閱讀 3,467評(píng)論 0 10