Swift設(shè)計(jì)模式:4.單例模式

單例模式(Adapter Pattern)

一.什么是單例模式:

確保某一個(gè)類只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例。

二.單例模式的優(yōu)點(diǎn):

1.由于單例模式在內(nèi)存中只有一個(gè)實(shí)例,減少了內(nèi)存開支,特別是一個(gè)對(duì)象需要頻繁的創(chuàng)建、銷毀時(shí),而且創(chuàng)建或銷毀時(shí)性能又無法優(yōu)化,單例模式的優(yōu)勢(shì)就非常明顯。

2.由于單例模式模式只生成一個(gè)實(shí)例,所以減少了系統(tǒng)的性能開銷,當(dāng)一個(gè)對(duì)象的產(chǎn)生需要比較多的資源時(shí),如讀取配置、產(chǎn)生其他依賴對(duì)象時(shí),則可以通過在應(yīng)用啟動(dòng)時(shí)直接產(chǎn)生一個(gè)單例對(duì)象,然后用永久駐留內(nèi)存的方式來解決。

3.單例模式可以避免對(duì)資源的多重占用,例如一個(gè)寫文件動(dòng)作,由于只有一個(gè)實(shí)例存在內(nèi)存中,避免對(duì)同一個(gè)資源文件的同時(shí)寫操作。

4.單例模式可以在系統(tǒng)設(shè)置全局的訪問點(diǎn),優(yōu)化和共享資源訪問。

三.單例模式的缺點(diǎn):

1.擴(kuò)展困難

2.對(duì)測(cè)試不利

3.與單一職責(zé)原則有沖突

四.單例模式的適用情況:

1.要求生成唯一序列號(hào)的環(huán)境

2.在這個(gè)項(xiàng)目中需要一個(gè)共享訪問點(diǎn)或共享數(shù)據(jù)

3.創(chuàng)建一個(gè)對(duì)象需要消耗的資源過多(如訪問IO和數(shù)據(jù)庫(kù)等資源)

4.需要定義大量的靜態(tài)常量和靜態(tài)方法的環(huán)境

五.Swift實(shí)現(xiàn)單例模式的方式:

1.設(shè)置一個(gè)靜態(tài)實(shí)例變量
2.初始化方法設(shè)為私有

class Singleton {
    
    static let sharedInstance = Singleton()
    private init(){
        
    }
}

六.單例模式的讀取線程安全:

由于單例是全局的,可以在多個(gè)地方同時(shí)調(diào)用。如果多個(gè)線程同時(shí)調(diào)用單例某個(gè)屬性的set和get方法,可能會(huì)get到一個(gè)錯(cuò)誤值,這個(gè)時(shí)候應(yīng)該如何處理呢?
1.使用同步隊(duì)列:

class Singleton {
    
    private let serialQueue = DispatchQueue(label:"SerialQueue")
    private var queueDic = [String: String]()
    
    static let sharedInstance = Singleton()
    private init(){
        
    }
    
    func setDicValue(value: String, for key: String){
        
        serialQueue.sync {
            self.queueDic[key] = value
        }
    }
    
    
    func getDicValue(for key: String) -> String? {
        var result: String?
        
        serialQueue.sync {
            result = queueDic[key]
        }
        return result
    }
}

2.使用異步隊(duì)列:

class Singleton {
    private let concurrentQueue = DispatchQueue(label: "ConcurrentQueue",  attributes: .concurrent, target: nil)
    private var queueDic = [String: String]()
    
    static let sharedInstance = Singleton()
    private init(){
        
    }
    
    func setDicValue(value: String, for key: String){
        
        concurrentQueue.async(flags: .barrier) {
            self.queueDic[key] = value
        }    
    }
    
    
    func getDicValue(for key: String) -> String? {
        var result: String?
        concurrentQueue.sync {
            result = queueDic[key]
        }
        return result
    }
}

這里使用柵欄函數(shù)的目的:

IMG_2755.PNG

demo地址:Singleton Pattern

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容