過去に3回ぐらいSingleton
パターンの記事を見かけた事がありますが、Singletonパターンと言い張るためには「インスタンスが1つしか生成されない事を保証する」という約束ごとがあります。
Beta3まではこれが言語仕様的に困難であり、過去に紹介されてきたものは
**「なんちゃってSingletonパターン」**だったわけなのですが、Xcode6 Beta4でアクセスコントロールが可能になり、ついに1インスタンスを保証する事ができるようになりました。
class Singleton {
private init() { // 1.イニシャライザをprivateに
}
class var instance: Singleton { // 2.インスタンスを取得するためのプロパティなり関数なりを用意し、共有インスタンスを返す
struct Instance {
static let i = Singleton()
}
return Instance.i
}
}
println(Singleton.instance === Singleton.instance) // true
let newInstance = Singleton() // コンパイルエラー(新しいインスタンスは生成できない ※ただし同じswiftファイル内からは生成できてしまうので別ファイルにするなど、注意が必要です(^_^;)
名前の付け方(instanceプロパティ)については、ちょっと悩みますね(sharedにすべきか等)。
Swift 1.2 での実装方法(2015/02/11追記)
クラスでも静的なプロパティが宣言できるようになりましたので、よりシンプルに書くことができるようになりました。
class Singleton {
private init() { // 1.イニシャライザをprivateに
}
static let instance = Singleton() // 2.staticとしてインタンスを用意
}
release noteによると、最初に静的プロパティへアクセスしたときに初期化が行われるようなので、振る舞いとしても問題なさそうです。
[2017/05/15追記]
以前の記事ではfinal class
にしてたのですが、イニシャライザをprivate
にした時点で派生クラスを生成することはできないと思いますので(?)削除しました(間違っていたらツッコミお願いします)。
シングルトンパターンの弊害
シングルトンパターンは便利なようで弊害も結構ありますので、本当にシングルトンにすべきかどうかは良く検討した方が良いです。
参考:[プログラマ97]シングルトンパターンの誘惑に負けない
私の周りの実体験だと、開発チームAが以下のような設計のアプリを開発
- データクラスが複数あって、それぞれがシングルトンパターンで実装されている
- データをバイナリファイルから読み込むと他の複数のシングルトンのデータクラスへそのデータを詰め込む感じ
以上が扱うデータは「個人」のデータとします。
後々、開発チームBがこの個人データを複数読み込み、数百人分のデータを集計したり様々な表やグラフにしたりするようなツールを開発することになりました。
(あらかじめ集計ツールが開発される事は予想されていた。)
集計ツールは若いエンジニアが担当したのですが、データクラスがSingleton
なので、複数のデータがメモリにロードできない(=ソースが流用できない)ってんで困り果ててました(Singleton
よいうよりエンジニア同士のコミュニケーション不足のような気もしますが最初から集計しやすいように作っておいてほしかった...)。