Swiftでシングルトンパターンを実装する方法はいくつかあるのでまとめました。
遅延初期化(lazy initialization)とスレッドセーフ(thread safety)を考慮された実装です。
遅延初期化はシングルトンのインスタンスを利用開始するまで当該インスタンスを生成しないことです。
スレッドセーフは複数のスレッドで同時にインスタンスの生成を試みても、誤って複数のインスタンスを生成しないことです。
この実装は以下のバージョンで確認しています。
- Xcode6 Beta3
structのstatic定数で定義 (推奨)
static
定数に初期化したインスタンスを保持する実装です。ただSwiftのclass
はstatic
定数を利用できないので、struct
でネストしてstatic
定数を保持しています。現状この実装方法が一番良いと言われています。
class Singleton {
class var sharedInstance : Singleton {
struct Static {
static let instance : Singleton = Singleton()
}
return Static.instance
}
}
グローバル定数で定義
グローバル定数に初期化したインスタンスを保持する実装です。グローバルに変数を保持するのは汚染と言われ推奨されませんが、今後Swiftの言語仕様が変更され局所的グローバル変数が定義できるようになれば、この実装方法がもっともシンプルになります。
let _SingletonSharedInstance = Singleton()
class Singleton {
class var sharedInstance : Singleton {
return _SingletonSharedInstance
}
}
dispatch_onceで実装
ObjCと同様の実装方法です。毎回これを書くにのは大変ですね。
class Singleton {
class var sharedInstance : Singleton {
struct Static {
static var onceToken : dispatch_once_t = 0
static var instance : Singleton? = nil
}
dispatch_once(&Static.onceToken) {
Static.instance = Singleton()
}
return Static.instance!
}
}