1. 程式人生 > >iOS中使用dispatch_once實現單例及注意事項

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

alloc]init];

    });

    return sharedInstance;

}

使用dispatch_once的注意事項:

    此函式接收型別為dispatch_once_t的特殊引數,還有一個塊引數。對於onceToken標記,該函式保證相關的塊必定會執行,且執行一次。此操作完全是執行緒安全的。注意:對於只執行一次的塊來說,對於傳入函式的標記引數必須完全相同,因此,開發時需要將標記變數宣告在static或global作用於中。

對於在dispatch_once中的建立的例項物件必須確保其只有一個,所以使用static修飾

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