[Swift]Singleton(シングルトン)とは?メリット、実装方法、使い方

[Swift]Singleton(シングルトン)とは?メリット、実装方法、使い方

こんにちは、こばやしよしのり @yoshiii514 です。

gimon
  • Singleton(シングルトン)がよくわからない
  • Swiftではどのように実現するのか

こういった悩みに答えるために、Swiftでのシングルトンのメリット、実装方法、使い方をわかりやすく解説しました。

前提となる知識

オブジェクト指向の基本がわからないと理解できないので、「オブジェクト指向でなぜつくるのか」ぐらいは読んでおくといいでしょう。とてもわかりやすい本です。

シングルトンにつていは、「Java言語で学ぶデザインパターン入門」でも解説されています。Java言語ですが、基礎知識は理解できます。とてもわかりやすい本で、おすすめ。

Xcode、Swiftの基礎学習をしていることも前提になります。初学者の方は、次の記事を参考に基礎学習を済ませてください。
 初心者向け iPhone(iOS)アプリ開発おすすめ本と勉強方法!

シングルトンとはなにか

  • シングルトンはオブジェクト指向言語にグローバル変数と同等の機能を実現させるためのもの
  • 指定したクラスのインスタンスが絶対に1個しか存在しないことを保証するもの

シングルトンはどんなときに使うのか、そのメリット

  • たくさんのインスタンスからアクセスされると困るとき
  • 毎回、インスタンス生成をするのが手間
  • 共通的な情報保持をして、メモリを節約したい

例えば

  • ログを出力機能、常に1つのインスタンスからファイルへ出力したい
  • 画面に出力(標準出力)、画面は1つなので1つのインスタンスから出力
  • 取得したJSONデータをどの画面でも使う時

Swiftでのシングルトンの実装

次のUserSettingsというクラスにシングルトンを実装する方法で解説します。


public class UserSettings {
    init() {} 
    private var settings: [String: Any] = ["Theme": "Vivid", "Brightness": 50] 
}

手順1.finalの付加

シングルトンは、継承(サブクラスの作成)を防ぐ必要があります。そのためfinalを付加します。


final public class UserSettings {}

手順2.init(イニシャライズ)をprivate

シングルトンであるためには、利用するときにシングルトンを直接インスタンス化しないようにすることです。init(イニシャライザ)をprivateにして隠すことで、これを実現できます。


private init() {}

privateキーワードは、イニシャライザが同じファイル内にあるクラス宣言とその拡張子内でしか使用できないことを保証します。ですが、このままではUserSettingsクラスは外部からインスタンスを作成することができません。

手順3.public staticプロパティの作成

UserSettingsインスタンスにpublic staticプロパティを利用して、外部からアクセスできるようにします。これをshared(シェアード:共有)と呼び、それにUserSettingsインスタンスを割り当てます。


public static let shared = UserSettings()

staticはインスタンス化されても、1つしか存在しません。すべてのインスタンスで共通です。
Swiftはstaticプロパティがスレッドセーフであることを保証しています。つまり、複数のスレッドが一度にstaticプロパティにアクセスした場合、複数のUserSettingsインスタンスが作成されてしまうリスクを心配するする必要がないということです。

スレッドセーフ(Thread-safe)
スレッドセーフは、マルチスレッドプログラミングにおける概念。あるコードがスレッドセーフであるという場合、そのコードを複数のスレッドが同時並行的に実行しても問題が発生しないことを意味する。

UserSettingsインスタンスのinit(イニシャライザ)はprivateで外部からアクセスできませんが、shared(public staticプロパティ)を外部から利用させることでインスタンス化できるようにします。

これで、シングルトン・インスタンスを使用できるようになりました。

手順4.シングルトンクラスで使うメソッドなどを実装する

次に、UserSettingsに格納されている値にアクセスするメソッドを提供します。最初に、指定されたキーの文字列を返すメソッドを実装します。ここでは、キーの型がStringで、結果としてオプションのString?を返します。


public func keyString(forkey key: String) -> String? {
    return settings[key] as? String
}

手順5.シングルトンを使う

シングルトンを使うときは、public staticプロパティであるsharedを窓口として利用します。


// シングルトンを使う
print(UserSettings.shared.keyString(forkey: "Theme"))   // Optional("Vivid")

最後に、今回のコード全体を掲載します。


// シングルトンクラス
final public class UserSettings {
    private init() {}
    private var settings: [String: Any] = ["Theme": "Vivid", "Brightness": 50]
    public static let shared = UserSettings()
    public func keyString(forkey key: String) -> String? {
        return settings[key] as? String
    }
}
// シングルトンを使う
print(UserSettings.shared.keyString(forkey: "Theme")) // Optional("Vivid")
参考図書
本記事の執筆では「Design Patterns in Swift 5」がとても参考になりました。英語ですが、ぜんぜんわかりやすい本でおすすめです😊


Design Patterns in Swift 5: Learn how to implement the Gang of Four Design Patterns using Swift 5. Improve your coding skills. (Swift Clinic) (English Edition)

この記事がお役に立てましたら、ぜひTwitterで感想をお聞かせください😊

動画で学ぶiOSアプリ開発講座を公開!
「体験しながら学ぶ」最短での脱初心者カリキュラムiPhoneアプリ開発集中講座[オンライン版]Mac・Xcode12・iOS14・Swift5.3・SwiftUI完全対応
「体験しながら学ぶ」ことで、最短での脱初心者を目指すアプリ開発講座です。

【本講座に含まれているもの】
・全額返金保証
・Swift文法解説
・SwiftUI完全対応
・サンプルアプリ6本作成
・チャットサポート(Slack)

執筆陣が徹底解説、サポートをします💪
 【先行ユーザー特典!先着10名様40,000円OFF】 iPhoneアプリ開発集中講座[オンライン版]