標籤:
原帖地址:http://www.galloway.me.uk/tutorials/singleton-classes/
本文為博主自行翻譯,轉載請註明出處:http://blog.csdn.net/iosevanhuang/article/details/13278323
“單例模式”是我在iOS中最常使用的設計模式之一。單例模式不需要傳遞任何參數,就有效地解決了不同代碼間的資料共用問題。
背景
單例類是一個非常重要的概念,因為它們表現出了一種十分有用的設計模式。單例類的應用貫穿於整個iPhone SDK中。例如,UIApplication類有一個方法叫sharedApplication,從任何地方調用這個方法,都將返回與當前正在啟動並執行應用程式相關聯的UIApplication執行個體。
博主補充:單例類保證了應用程式的生命週期中有且僅有一個該類的執行個體對象,而且易於外界訪問。
實現
你可以用以下代碼實現一個Objective-C的單例類(ARC模式下,非ARC模式下面會講到):
1 2 3 4 5 6 7 8 9 10 11 |
#import <foundation/Foundation.h> @interface MyManager : NSObject {NSString *someProperty;} @property (nonatomic, retain) NSString *someProperty; + (id)sharedManager; @end |
來自CODE的代碼片MyManager.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#import "MyManager.h" @implementation MyManager @synthesize someProperty; #pragma mark Singleton Methods + (id)sharedManager {static MyManager *sharedMyManager = nil;static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{sharedMyManager = [[self alloc] init];});return sharedMyManager;} - (id)init {if (self = [super init]) {someProperty = [[NSString alloc] initWithString:@"Default Property Value"];}return self;} - (void)dealloc {// 永遠不要調用這個方法} @end |
來自CODE的代碼片MyManager.m
在這裡我們定義了一個靜態變數sharedMyManager,然後僅初始化一次該變數。這裡使用了dispatch_once以保證該變數只被GCD初始化一次。作業系統將保證這是安全執行緒的。
如果不使用GCD,你可以使用以下代碼:
1 2 3 4 5 6 7 8 |
+ (id)sharedManager {static MyManager *sharedMyManager = nil;@synchronized(self) {if (sharedMyManager == nil)sharedMyManager = [[self alloc] init];}return sharedMyManager;} |
來自CODE的代碼片Non-GCD-based-code.m 接下來,當你需要使用這個單例對象時,你只要這樣調用就可以了:
1 |
MyManager *sharedManager = [MyManager sharedManager]; |
來自CODE的代碼片snippet_file_0.m我在My Code中廣泛使用單例類,比如建立一個單例類來處理CoreLocation或CoreData功能。
非ARC代碼雖然我並不那麼推薦,但是如果你要使用非ARC環境的話,你應該使用以下代碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
#import "MyManager.h" static MyManager *sharedMyManager = nil; @implementation MyManager @synthesize someProperty; #pragma mark Singleton Methods+ (id)sharedManager {@synchronized(self) {if(sharedMyManager == nil)sharedMyManager = [[super allocWithZone:NULL] init];}return sharedMyManager;}+ (id)allocWithZone:(NSZone *)zone {return [[self sharedManager] retain];}- (id)copyWithZone:(NSZone *)zone {return self;}- (id)retain {return self;}- (unsigned)retainCount {return UINT_MAX; // 表示該對象永遠不應被釋放}- (oneway void)release {// 從不釋放}- (id)autorelease {return self;}- (id)init {if (self = [super init]) {someProperty = [[NSString alloc] initWithString:@"Default Property Value"];}return self;}- (void)dealloc {// 從不調用該方法[someProperty release];[super dealloc];} @end |
來自CODE的代碼片MyManager-non-ARC.m博主:這裡的單例都是懶漢式單例,當單例對象的擷取方法第一次被調用時建立單例對象。而在類被載入時就建立單例對象叫做餓漢式單例。
ios之單例模式