單例模式

單例模式

單例模式確保爲一個確定的類只有一個實例存在,而且有一個全局的訪問指針只想它,他經常使用延時加載去在第一次使用的時候創建一個簡單的實例。

           小貼士:蘋果使用這個方法很頻繁。比如:[NSUserDefaults standarUserDefaults], [UIApplicationsharedApplication],[UIScreen mainScreen],[NSFileManager defaultManager],都返回一個單例。

你可能會以爲爲什麼你會介意一個類周圍會有不止一個實例,代碼和內存都很簡化,對不對?

有一些情況下一個類只有一個實例會很有意義。比如:沒有必要去有很多的Logger實例,除非你想要同時寫入幾個日記文件,或者,擁有一個全聚德配置控制的類,很容易就實現一個線程安全的單個共享資源,比如配置文件,而不是多個類同時修改同一個配置文件。

如何使用單例

看一下右邊的這個圖表:

它顯示了一個Logger類只有一個屬性,(也是一個實例),和兩個方法init和sharedInstance;

第一次客戶端發送sharedInstance消息,這和屬性的實例還沒有初始化,所以你要創建這個類的一個新的實例然後返回一個指針指向它。

下一次你調用sharedInstance方法,實例就會立馬返回而不需要任何的初始化,這個邏輯保證任何時候都只有一個實例存在。

你將要實現這和模式通過創建一個單例的類去管理所有的album 數據。

你將會意識到在這個組中有一個叫做API的租在這個工程中,這是你將會將所有的提供給你的app服務的類放到其中。在這個組中創建一個叫做LibraryAPI的類,繼承於NSObject。

打開LibraryAPI.h,加入以下方法:


  1. +(LibraryAPI*)sharedInstance;  



在LibraryAPI.m中加入這些方法:

+(LibraryAPI*) sharedInstance{  
   
//1  
   
staticLibraryAPI* _sharedInstance;  
   
//2  
   
staticdispatch_once_t once;  
   
//3  
   
   dispatch_once(&once,^{  
   
       _sharedInstance = [[LibraryAPI alloc]init];  
   
   });  
   
    
   return _sharedInstance;  
   
}

這個簡單的方法中有很多內容:

1.    定義了一個靜態變量去hold住類中的實例,確保它是全局可用的在你的類中。

2.    定義了一個靜態變量dispatch_once_t類型的去確保這個初始化代碼只執行一次。

3.    使用Grand Central Dispatch(GCD)去執行一個初始化LibraryAPI的實例的block,這就是單例設計模式的本質:這個初始化永遠不會再次被調用一旦這個類被實例化。

下次你調用sharedInstance方法是,這個dispatch_once裏面的block代碼不會被執行了,你會得到一個先前創建這個LibraryAPI的一個引用。

現在你有了一個單例對象作爲albums的入口指針,更進一步去創建一個類去處理庫中數據的持久化。

在API組中創建一個PersistencyManager的繼承於NSObject的類。打開它的.h文件,加入

#import “Album.h”再加入以下代碼:

- (NSArray *)getAlbums;  
- (void)addAlbum:(Album *)album atIndex:(int)index;  
- (void)deleteAlbumAtIndex:(int)index;



以上是加入了三個方法去處理數據的。

打開.m文件在 @implemetation的上方加入這些代碼:

@interface PersistencyManager () {  
   
   // an array of all albums  
   
   NSMutableArray *albums;  
   
}



上面的代碼添加了一個類擴展,這是另一個添加私有變量和方法帶類中所以外部的類並不只帶他們,在這裏,你聲明瞭一個可變數組去hold住album的數據,這個數據是可變的以便你可以輕鬆地添加和刪除專輯。

現在添加下面代碼到PersistencyManager.m中去

- (id)init  
{  
    self = [super init];  
    if (self) {  
        albums = [NSMutableArray arrayWithArray:@[[[Album alloc] initWithTitle:@"Best of Bowie" artist:@"David Bowie" coverUrl:@"http://www.coversproject.com/static/thumbs/album/album_david%20bowie_best%20of%20bowie.png" year:@"1992"],  
                                           [[Album alloc] initWithTitle:@"It's My Life" artist:@"No Doubt" coverUrl:@"http://www.coversproject.com/static/thumbs/album/album_no%20doubt_its%20my%20life%20%20bathwater.png" year:@"2003"],  
                                           [[Album alloc] initWithTitle:@"Nothing Like The Sun" artist:@"Sting" coverUrl:@"http://www.coversproject.com/static/thumbs/album/album_sting_nothing%20like%20the%20sun.png" year:@"1999"],  
                                           [[Album alloc] initWithTitle:@"Staring at the Sun" artist:@"U2" coverUrl:@"http://www.coversproject.com/static/thumbs/album/album_u2_staring%20at%20the%20sun.png" year:@"2000"],  
                                           [[Album alloc] initWithTitle:@"American Pie" artist:@"Madonna" coverUrl:@"http://www.coversproject.com/static/thumbs/album/album_madonna_american%20pie.png" year:@"2000"]]];  
    
    }  
       
    return self;  
}  
-(NSArray *)getAlbums  
{  
    return albums;  
}  
   
-(void)addAlbum:(Album *)album atIndex:(int)index  
{  
    if (index < [albums count]) {  
        [albums insertObject:album atIndex:index];  
    }else{  
        [albums addObject:album];  
    }  
}  
   
- (void)deleteAlbumAtIndex:(int)index  
{  
    [albums removeObjectAtIndex:index];  
}

在init這個初始化函數中你用五個實例轉會填充了這個數組,其他幾個方法允許你去得到,添加額刪除albums。編譯你的工程確保仍能正確編譯。

在這個時候你可能會疑問爲什麼PersistenceManager不是單例,它和LibraryAPI的關係會下下一部分的外觀(Faade)設計模式中見到。


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