【Swift】よく見る『.shared』・シングルトンの意味
公開日:
はじめに
let foo = Hoge.shared // いやsharedってなに
このようなshared
を使った実装を見たことがある人は多いかもしれません。
これは大体の場合、シングルトンというデザインパターンに基づいて実装されています。
『シングルトン』とは
シングルトンとは簡単にいうと
インスタンスが”1 つ”しか生成されないことが保証されているクラス
です。簡単な例だと、
// シングルトンの例
class SingletonExample {
// インスタンスを参照するためのプロパティ
static let shared = SingletonExample()
// 適当なプロパティ
var greeting: String = "おはよう"
// privateなイニシャライザ
private init() {}
}
// シングルトンを参照①
let hoge = SingletonExample.shared
print(hoge.greeting) // "おはよう"
// シングルトンを参照②
let fuga = SingletonExample.shared
// シングルトンのプロパティを変更
fuga.greeting = "hello"
print(hoge.greeting) // "hello"
こんな感じ。
普通のクラスのようにインスタンスを生成しようとしてもイニシャライザがprivate
なので、エラーが出てしまいます。
なので、シングルトンのインスタンスを参照するにはshared
プロパティを用いて、”1 つ”のインスタンスを参照するしかありません。
参照するためのプロパティの名前はなんでもいいですが、シングルトンパターンだということがわかりやすいようにshared
という名前をつける慣習があるようです。
インスタンスが”1 つ”しか生成されないことが保証されているわけですね。
いつ使うの?
シングルトンがどういうものかは理解したとしても、結局一番知りたいのは使う場面。
結論から言いますと、シングルトン不要論みたいなのもあるらしく、そんなに頻出で絶対に必要なものではありません。
というのも、前回の記事で書いたstatic
キーワードで代用できる場合が多いです。
https://www.yukendev.com/blogs/swift-static
- インスタンスが 1 つしかないことを保証する
- インスタンス化せずにプロパティやメソッドを使う
この二つは無駄なインスタンスを生成しないという点で似ている概念です。自分のインターン先のコードでは、下のコードのように UserDefaults を使うときにシングルトンが使われていました。
final class SingletonUserDefaults {
static var shared = SingletonUserDefaults()
private init() {}
private lazy var userDefaults = UserDefaults.standard
var mailAddress: String {
get {
return userDefaults.string(forKey: "MailAddress") ?? ""
}
set(value) {
userDefaults.set(value, forKey: "MailAddress")
}
}
}
// 呼び出し
let UD = SingletonUserDefaults.shared
print(UD.mailAddress)
先輩のエンジニアになぜここでシングルトンを採用したのか聞いてみたところ、
「使用箇所が多くてその都度インスタンス化していたらメモリが勿体無かったからですね。」
とのこと。また、
「変数を全部 static にすれば、シングルトンじゃなくても実装できますよ。」
とも言っていました。やっぱり、シングルトンと static は割と似ているんですね。なので自分はやっぱり
staticでいいんじゃないか??
ってなってしまいます。そこら辺を詳しく知りたい方は、こちらの記事がわかりやすかったです。
https://medium.com/swift-column/singleton-398078bcc58d
まとめ
シングルトンとはインスタンスが”1 つ”しか生成されないことを保証されているクラスである。
でも、大体の場合staticを使って置き換えることができるのでstaticでよくね?ってなりました。この記事はあくまで僕が自分で調べたり、ソースコードを見て学んだことのアウトプットなので間違っていたり、もっと魅力的なシングルトンの使い方があるかもしれません。その場合は、教えていただけるとありがたいです。
では
Bye