iOS 8:dispatch_once解惑

來源:互聯網
上載者:User

標籤:

關鍵字:GCD  dispatch_once  單例  安全執行緒  double-check

  以前在Java、C#等語言中,我們實現遲緩載入的單例模式一般寫成如下形式(虛擬碼):

private MyClass() {...} // 私人化構造方法

private static MyClass instance; // 承載對象的變數

pubic static MyClass getInstance() { // 完成執行個體化任務

  if (instance == null) { // 第一次判斷

    lock (obj) { // 加鎖,處理多線程判斷

      if (instance == null) {// 再次判斷,避免線程切換導致多個執行個體對象出現

        instance = new MyClass(); // 完成最終執行個體化過程

      }

    }

  }

  return instance;
}

  但是,在Objective-C中經常看到的卻是這種寫法:

+ (instancetype)sharedInstance {

  static id sharedInstance;

  static dispatch_once_t onceToken;

  dispatch_once(&onceToken, ^{

    sharedInstance = [self new];

  });

  return sharedInstance;

}

  這種寫法似乎並沒對多線程編程作防禦性處理。在sharedInstance = [self new];前後加入日誌輸出,可發現,即使在多線程環境下,dispatch_once也只執行一次。

  其實,dispatch_once是安全執行緒的,即使在多個線程中同時調用,也只有一個塊被執行,其它dispatch_once塊的調用被阻塞,直到執行的那個塊運行結束,所以在整個程式運行周期內,dispatch_once塊只會運行一次,可以確定,下一行代碼執行前,整個dispatch_once塊是執行完畢的,不管當前背景工作執行緒是哪個。如果已執行,dispatch_once會被快速跳過,在類似迴圈體中調用這種場合,也無需擔心執行它的額外效能開銷。如果一個程式包含多個同一調用類的執行個體,只有其中一個執行個體會執行dispatch_once塊[1]。

參考:

[1]. Rob Napier 等著, 美團移動 譯. iOS編程實戰. 北京, 人民郵電出版社. 358~359頁

iOS 8:dispatch_once解惑

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.