只能生成一個實例的類是實現了Singleton模式的類型。由於設計模式在面向對象程序設計中起着舉足輕重的作用,在常用的模式中,singleton是唯一一個能夠用短短几十行代碼完整實現的模式。
static PPLAccountManager *sharedInstance
= nil;
1.最簡單(非線程安全)
+ (PPLAccountManager*)sharedManager {
if (sharedInstance ==nil) {sharedInstance = [[self alloc]init];
}
return sharedInstance;
}
單線程下運行正常,但是在多線程下就有問題了。如果兩個線程同時運行到判斷shareInstance是否爲nil的if語句,且shareInstance沒有創建時候,那麼2個線程都會創建一個實例,此時單例就不在滿足單例模式的要求了。爲了保證多線程環境下我們還是隻能得到類型的一個實例,需要加上一個同步鎖。如下:
2.線程安全(不是最優)
+ (PPLAccountManager*)sharedManager {
@synchronized(self){if (sharedInstance == nil) {
sharedInstance = [[selfalloc]init];
}
return sharedInstance;
}
}
這裏還不是很完美。我們還是設想兩個線程同時想創建一個實例,由於同一時刻只能有一個能得到同步鎖,每當第一個線程鎖加上鎖,第二個線程只能等待,當第一個線程發現實例還沒有創建時,它創建一個實例。接着第一個線程釋放同步鎖,此時第二個線程可以加上同步鎖,並運行接下來的 代碼。我們每次得到單例實例,都會試圖加上一個線程鎖,而加鎖是一個非常耗時的操作,在沒有必要的時候,我們儘量要避免。
3.線程安全(邏輯複雜)
+ (PPLAccountManager*)sharedManager {
if (sharedInstance == nil) {
@synchronized(self){
if (sharedInstance == nil) {
sharedInstance = [[self alloc]init];
}
}
}
return sharedInstance;
}
這裏用了2個if判斷來提高效率,但是代碼實現邏輯比較複雜,容易出錯,我們還有更加優秀的的解法。4.最優算法(官方推薦)
+ (PPLAccountManager*)sharedManager {
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
sharedInstance = [[self alloc] init]; });
return sharedInstance;
}
}