單例(單態)模式
單例設計模式確保對於一個給定的類只有一個實例存在,這個實例有一個全局惟一的訪問點。它一般採用懶加載的方式在第一次用到實例的時候再去建立它。
注意:蘋果大量使用了此模式。例如:[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,用以下代碼替換它的內容
- @interfaceLibraryAPI : NSObject
-
- + (LibraryAPI*)sharedInstance;
-
- @end
如今打開LibraryAPI.m,在@implementation 那一行後面插入下面的方法:
- + (LibraryAPI*)sharedInstance
- {
-
- static LibraryAPI *_sharedInstance = nil;
-
-
- static dispatch_once_t oncePredicate;
-
-
- dispatch_once(&oncePredicate, ^{
- _sharedInstance = [[LibraryAPI alloc] init];
- });
- return _sharedInstance;
- }
在這個簡短的方法中,有一些須要須要注意的點:
1.聲明一個靜態變量去保存類的實例,確保它在類中的全局可用性。
2.聲明一個靜態變量dispatch_once_t ,它確保初始化器代碼只執行一次
3.使用Grand Central Dispatch(GCD)執行初始化LibraryAPI變量的block.這 正是單例模式的關鍵:一旦類已經被初始化,初始化器永遠不會再被調用。
下一次你調用sharedInstance的時候,dispatch_once塊中的代碼將不會執行(由於它已經被執行了一次),你將獲得原先已經初始化好的實例。