Swift辛格爾頓設計模式(SINGLETON)


本文已更新爲2.0語法,具體查看:一葉單例模式



1、意圖

保證一個類公有一個實例。並提供一個訪問它的全局訪問點。javascript


2、使用場景

一、使用場景java

  • 當類僅僅能有一個實例而且客戶可以從一個衆所周知的訪問點訪問它時
  • 當這個惟一實例應該是經過子類化可擴展的,而且客戶應該無需更改代碼就能使用一個擴展的實例時。


二、實現的重要三個步驟
  • 私有化構造方法(Swift不支持)
  • 使用一個靜態變量保存實例的引用 
  • 提供一個全局的訪問方法

 3、 Swift語言下的實現

Swift語言不支持變量及方法的權限,沒有辦法隱藏變量及方法,可以任意直接建立一個實例。

單例的建立有很是多寫法,Swift支持僅僅有struct支持靜態變量。class不支持靜態變量。因此很是easy想到,在類的內部使用struct就能解決引用的保存問題,代碼例如如下:swift

class SwiftSingleton {
    class var shared: SwiftSingleton {
        dispatch_once(&Inner.token) {
            Inner.instance = SwiftSingleton()
        }
        return Inner.instance!
    }
    struct Inner {
        static var instance: SwiftSingleton?
        static var token: dispatch_once_t = 0
    }
    
}

執行例如如下測試代碼。進行簡單測試:
class SwiftSingletonTest: XCTestCase {
    
    
    func testSingleton() {
        let singleton1 = SwiftSingleton.shared
        let singleton2 = SwiftSingleton.shared
        assert(singleton1 === singleton2, "pass")
    }
    
}

執行結果,左側綠色對號表明執行經過:

當中===在Swift中表明「等價於」,比較的是兩個變量或者常量的引用地址,僅僅能用於class的比較

在Swift中static類型變量會本身主動實現成延遲載入模式。也可以更簡單的實現成例如如下:
class SwiftSingleton {
    class var shared: SwiftSingleton {
        return Inner.instance
    }
    
    struct Inner {
        static let instance = SwiftSingleton()
    }
}

在所有語言中單例分爲懶漢模式(延遲載入),餓漢模式,通常爲了不資源浪費,都喜歡實現成懶漢模式。即便用時在生成實例。在Swift語言中,由於statickeyword作了優化。本身主動實現了 延遲載入模式。因此上面的代碼實現的是懶漢模式而並非餓漢模式


4、可能引發錯誤的實現

class與struct一個很重要的差異:
class:傳引用
struct:傳值
有部分人可能想經過struct來直接實現單例模式,由於struct傳遞時是傳的值。會形成內存中有多個拷貝。測試例如如下:
struct SwiftSingleton {
    var name: String = "1"
    static let shared = SwiftSingleton()
}


var single1 = SwiftSingleton.shared
var single2 = SwiftSingleton.shared

single2.name = "2"

println("------->\(single1.name)")
println("------->\(single2.name)")

打印結果例如如下:
------->1
------->2
Program ended with exit code: 0

從上面可以看到,經過struct下的實現,咱們不能保證只有一個實例,這樣的實現是一個問題

版權聲明:本文博客原創文章。博客,未經贊成,不得轉載。優化

相關文章
相關標籤/搜索