天天看點

iOS中使用dispatch_once實作單例及注意事項

單例模式實作方式是在類中編寫名為sharedInstance的方法,該方法隻會傳回全類共用的單例執行個體,而不會在每次調用時都建立新的執行個體。

 使用同步塊實作:

+ (id)sharedInstance {

    static ClassName *sharedInstance = nil;

    @synchronized (self) {

        if (!sharedInstance) {

            sharedInstance = [[self alloc]init];

        }

    }

    return sharedInstance;

}

GCD引入了一個新特征,更為友善:

+ (instancetype)sharedInstance {

    static ClassName *sharedInstance = nil;

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        sharedInstance = [[self alloc]init];

    });

    return sharedInstance;

}

使用dispatch_once的注意事項:

    此函數接收類型為dispatch_once_t的特殊參數,還有一個塊參數。對于onceToken标記,該函數保證相關的塊必定會執行,且執行一次。此操作完全是線程安全的。注意:對于隻執行一次的塊來說,對于傳入函數的标記參數必須完全相同,是以,開發時需要将标記變量聲明在static或global作用于中。

對于在dispatch_once中的建立的執行個體對象必須確定其隻有一個,是以使用static修飾

    上述兩種實作單例的方法比較:使用dispatch_once可以簡化代碼且保證線程安全,開發者無需擔心加鎖或同步。所有問題都在GCD底層處理。此外,dispatch_once更高效。它沒有使用重量級的同步機制。使用同步機制,每次運作代碼都需要擷取鎖。dispatch_once采用“原子通路”來查詢标記,判斷代碼是否執行過。

iOS