理解 單例模式

單例(單態)模式
單例設計模式確保對於一個給定的類只有一個實例存在,這個實例有一個全局惟一的訪問點。它一般採用懶加載的方式在第一次用到實例的時候再去建立它。
 
注意:蘋果大量使用了此模式。例如:[NSUserDefaults standardUserDefaults], [UIApplication sharedApplication], [UIScreen mainScreen], [NSFileManager defaultManager],全部的這些方法都返回一個單例對象。
 
你極可能會想爲何這麼關心是否一個類有多個實例?畢竟代碼和內存都是廉價的,對嗎? 
 
有一些狀況下,只有一個實例顯得很是合理。舉例來講,你不須要有多個Logger的實例,除非你想去寫多個日誌文件。或者一個全局的配置處理類:實現線程安全的方式訪問共享實例是容易的,好比一個配置文件,有好多個類同時修改這個文件。
 
如何使用單例模式
首先來看看下面的圖:
 
上面的圖描述了一個有單一屬性(它就是單一實例)和sharedInstance,init兩個方法的類。
 
客戶端第一次發送sharedInstance消息的時候,instance屬性還沒有被初始化,因此此時你須要建立一個新的實例,而後返回它的引用。
 
當你下一次調用sharedInstance的時候,instance不須要任何初始化能夠當即返回。這個邏輯保證老是隻有一個實例。
 
你接下來將用這個模式來建立一個管理全部專輯數據的類。
 
你將注意到工程中有一個API的組,在這個組裏你能夠放入給你應用提供服務的全部類。在此組中,用IOS\Cocoa Touch\Objective-C class 模板建立一個新類,命名它爲LibraryAPI,設置父類爲NSObject.
 
打開LibraryAPI.h,用以下代碼替換它的內容
  1. @interfaceLibraryAPI : NSObject   
  2.     
  3. + (LibraryAPI*)sharedInstance;   
  4.     
  5. @end   
 
如今打開LibraryAPI.m,在@implementation 那一行後面插入下面的方法:
  1. + (LibraryAPI*)sharedInstance   
  2. {   
  3.     // 1   
  4.     static LibraryAPI *_sharedInstance = nil;   
  5.     
  6.     // 2   
  7.     static dispatch_once_t oncePredicate;   
  8.     
  9.     // 3   
  10.     dispatch_once(&oncePredicate, ^{   
  11.         _sharedInstance = [[LibraryAPI alloc] init];   
  12.     });   
  13.     return _sharedInstance;   
  14. }   
在這個簡短的方法中,有一些須要須要注意的點:
1.聲明一個靜態變量去保存類的實例,確保它在類中的全局可用性。
2.聲明一個靜態變量dispatch_once_t ,它確保初始化器代碼只執行一次
3.使用Grand Central Dispatch(GCD)執行初始化LibraryAPI變量的block.這  正是單例模式的關鍵:一旦類已經被初始化,初始化器永遠不會再被調用。
 
下一次你調用sharedInstance的時候,dispatch_once塊中的代碼將不會執行(由於它已經被執行了一次),你將獲得原先已經初始化好的實例。 
 
注意: 爲了學習更多關於GCD方面的信息以及如何使用,請查看本站指南 Multithreading and Grand Central Dispatch 和  How to Use Blocks
 
相關文章
相關標籤/搜索