單例模式是日常開發工作中經常會用到的一種設計模式。通過單例模式,可以保證程序中的一個類只有一個實例,從而方便對實例個數的控制以節省系統資源。因此,如果希望系統中的某個類只有一個實例,那單例模式是比較好的解決方案。
iOS開發中,最常見的單例就是UIApplication。
簡單介紹一下iOS中如何實現單例設計模式。
在iOS中,所有對象內存空間的分配,最終都會調用 allocWithZone方法。也就是說,當我們寫下如下代碼時:
UIButton *btn = [[UIButton alloc] init];
實際上會調用 allocWithZone 方法。因此實現單例時,可以重寫 allocWithZone 方法。
另外,GCD 提供了一個方法,是專門用來創建單例的。提供的是 dispatch_once 宏。可以保證塊代碼中的指令只被執行一次,且多線程時,是線程安全的,類只會被實例化一次。
重寫 allocWithZone 方法的代碼:
//重寫allocWithZone方法實現單例
//GCD提供了一個方法來創建單例,該方法是線程安全的
+ (id)allocWithZone:(struct _NSZone *)zone
{
static Singleton *instance;
//dispatch_once是線程安全的,onceToken默認為0
//且dispatch_once 可以保證塊代碼中的指令只被執行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [super allocWithZone:zone];
});
return instance;
}
這樣,再實例化類對象時,實際上返回的是一個唯一對象。
為了方便外界訪問該實例,可以實現一個 shared***方法,返回該類的實例,代碼如下:
+ (instancetype)sharedSingleton
{
return [[self alloc] init];
}
驗證代碼如下:
- (void)viewDidLoad {
[super viewDidLoad];
Singleton *single = [[Singleton alloc] init];
NSLog(@"single = %@",single);
Singleton *single2 = [Singleton sharedSingleton];
NSLog(@"single2 = %@",single2);
for(int i = 0; i < 10; ++i){
Singleton *testSingle = [[Singleton alloc] init];
NSLog(@"testSingle = %@",testSingle);
}
}
執行結果:
可以看出,無論是多次 alloc ,還是 shared***,得到的實例對象內存地址都是一樣的,說明類的實例只有一個。