原帖地址: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 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,你可以使用以下代碼:
接下來,當你需要使用這個單例對象時,你只要這樣調用就可以了:
我在我的代碼中廣泛使用單例類,比如創建一個單例類來處理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
博主:這里的單例都是懶漢式單例,當單例對象的獲取方法第一次被調用時創建單例對象。而在類被加載時就創建單例對象叫做餓漢式單例。