iOS 三種單例創(chuàng)建方式的優(yōu)缺點(diǎn)

一、單線程模式單例

// 單線程單例
+(instancetype)sharedLoadData
{
  static Singleton *singleton;
  if (!singleton ) {
    singleton = [[Singleton alloc] init];
  }
  return singleton;
}
  • 單線程單例只有在單個(gè)線程使用的情況下實(shí)用,在多線程的情況下,會產(chǎn)生線程不安全的情況。嚴(yán)格意義上來說,我們還需要把a(bǔ)lloc方法變?yōu)樗接蟹椒ú判校瑖?yán)格的單例是不允許再創(chuàng)建其他實(shí)例的,而alloc方法可以在外部任意生成實(shí)例。換句話說,假如在兩條線程里調(diào)用sharedLoadData方法,可能會產(chǎn)生兩個(gè)singleton實(shí)例,這樣單例就失去意義了。

二、多線程加鎖單例

// @synchronized加鎖
+(instancetype)sharedLoadData
{
    static Singleton *singleton;
    @synchronized (self) {
    if (!singleton) {
        singleton = [[Singleton alloc] init];
      }
    }
    return singleton;
}
  • 加鎖以后,當(dāng)多個(gè)線程同時(shí)調(diào)用shareInstance時(shí),由于@synchronized已經(jīng)加鎖,只能有一個(gè)線程創(chuàng)建singleton實(shí)例。這樣就解決了第一種情況的弊端。
    但是也有缺點(diǎn):只有在singleton未創(chuàng)建時(shí),加鎖才是必要的。如果singleton已經(jīng)創(chuàng)建,這個(gè)時(shí)候還加鎖的話,會影響性能。

三、系統(tǒng)GCD創(chuàng)建單例

+(instancetype)sharedLoadData
{
    static Singleton *singleton = nil;
    static dispatch_once_t onceToken;
    // dispatch_once  無論使用多線程還是單線程,都只執(zhí)行一次
    dispatch_once(&onceToken, ^{
        singleton = [[Singleton alloc] init];
    });
    return singleton;
}
  • GCD創(chuàng)建單例不僅可以解決多條線程的線程安全問題,也能保證性能,是官方推薦的方式。

  • dispatch_once主要是根據(jù)onceToken的值來決定怎么去執(zhí)行代碼。
    1.當(dāng)onceToken = 0時(shí),線程執(zhí)行dispatch_once的block中代碼
    2.當(dāng)onceToken = -1時(shí),線程跳過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)?40734537148864。當(dāng)其他線程再調(diào)用shareInstance方法時(shí),onceToken的值已經(jīng)是140734537148864了,線程阻塞。當(dāng)block線程執(zhí)行完block之后,onceToken變?yōu)?1.其他線程不再阻塞,跳過block。下次再調(diào)用shareInstance時(shí),block已經(jīng)為-1.直接跳過block。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,666評論 1 32
  • 經(jīng)常用到單例,但也僅僅是停留在會用的層次,至于為什么這么用,內(nèi)部怎么實(shí)現(xiàn)的,從未研究過。在面試的時(shí)候,被問到了單例...
    YSL一路行走閱讀 2,671評論 5 29
  • 前言 單例應(yīng)該是iOS中很簡單的設(shè)計(jì)模式,寫個(gè)單例很簡單很方便。網(wǎng)上例子也很多,大家也是基本上copy下來就可以了...
    楓葉無處漂泊閱讀 5,880評論 0 12
  • 概要 單例模式是常見的設(shè)計(jì)模式。它的核心結(jié)構(gòu)中只包含一個(gè)被稱為單例類的特殊類。 通過單例模式可以保證系統(tǒng)中單例類只...
    NapoleonY閱讀 327評論 0 1
  • 單例介紹 本文源碼下載地址 1.什么是單例 說到單例首先要提到單例模式,因?yàn)閱卫J绞菃卫嬖诘哪康?單例模式是一...
    雷鳴1010閱讀 3,707評論 0 19

友情鏈接更多精彩內(nèi)容