IOS開發之dispatch_once創建單例

轉載自:http://blog.csdn.net/sanpintian/article/details/8140671


單例是一種類,該類只能在第一次用的時候實例化一個對象,後期直接調用此對象(有點共享的意思)。
在Foundation框架中比如NSFileMangerNSNotificationCenter,分別通過它們的類方法defaultManagerdefaultCenter獲取。儘管不是嚴格意義的單例,這些類方法返回一個可以在應用的所有代碼中訪問到的類的共享實例。使用Objective-C實現單例模式的最佳方式向來有很多爭論,開發者似乎每幾年就會改變他們的想法。他們也引入了一個很適合用於實現單例模式的函數。
該函數就是dispatch_once
void dispatch_once( dispatch_once_t *predicate, dispatch_block_t block);
該函數接收一個dispatch_once用於檢查該代碼塊是否已經被調度的謂詞(是一個長整型,實際上作爲BOOL使用)。它還接收一個希望在應用的生命週期內僅被調度一次的代碼塊,對於本例就用於shared實例的實例化。
dispatch_once不僅意味着代碼僅會被運行一次,而且還是線程安全的,這就意味着你不需要使用諸如@synchronized之類的來防止使用多個線程或者隊列時不同步的問題。
如果被多個線程調用,該函數會同步等等直至代碼塊完成。
   實際要如何使用這些呢?
   好吧,假設有一個AccountManager類,你想在整個應用中訪問該類的共享實例。你可以按如下代碼簡單實現一個類方法:
+ (AccountManager *)sharedManager {
   static AccountManager *sharedAccountManagerInstance = nil;
   static dispatch_once_t predicate;

   dispatch_once(&predicate, ^{      

         sharedAccountManagerInstance = [[self alloc] init];
   });

   return sharedAccountManagerInstance;
}
這就意味着你任何時候訪問共享實例,需要做的僅是:
AccountManager *accountManager = [AccountManager sharedManager];
   就這些,你現在在應用中就有一個共享的實例,該實例只會被創建一次。
   該方法有很多優勢:
          1 線程安全
          2 很好滿足靜態分析器要求
          3 和自動引用計數(ARC)兼容
          4 僅需要少量代碼

該方法的劣勢就是它仍然運行創建一個非共享的實例:
AccountManager *accountManager = [[AccountManager alloc] init];
   有些時候你希望有這種行爲,但如果正在想要的是僅一個實例被實例化就需要注意這點。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章