iOS中使用dispatch_once實現單例及注意事項
單例模式,是一種常用的軟體設計模式。在它的核心結構中只包含一個被稱為單例的特殊類。通過單例模式可以保證系統中,應用該模式的類一個類只有一個例項。即一個類只有一個物件例項。
在iOS中單例模式實現方式是在類中編寫名為sharedInstance的方法,該方法只會返回全類共用的單例例項,而不會在每次呼叫時都建立新的例項。
使用同步塊實現:
+ (id)sharedInstance {
static ClassName *sharedInstance = nil;
@synchronized (self) {
if (!sharedInstance) {
sharedInstance = [[self alloc]init];
}
}
return sharedInstance;
}
GCD引入了一個新特徵,更為方便:
+ (instancetype)sharedInstance {
staticClassName *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self
});
return sharedInstance;
}
使用dispatch_once的注意事項:
此函式接收型別為dispatch_once_t的特殊引數,還有一個塊引數。對於onceToken標記,該函式保證相關的塊必定會執行,且執行一次。此操作完全是執行緒安全的。注意:對於只執行一次的塊來說,對於傳入函式的標記引數必須完全相同,因此,開發時需要將標記變數宣告在static或global作用於中。
對於在dispatch_once中的建立的例項物件必須確保其只有一個,所以使用static修飾
上述兩種實現單例的方法比較:使用dispatch_once可以簡化程式碼且保證執行緒安全,開發者無需擔心加鎖或同步。所有問題都在GCD底層處理。此外,dispatch_once更高效。它沒有使用重量級的同步機制。使用同步機制,每次執行程式碼都需要獲取鎖。dispatch_once採用“原子訪問”來查詢標記,判斷程式碼是否執行過。