[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で感想をお聞かせください😊

アプリ開発が学べる勉強会を開催中!
プログラミング初心者向け、アプリ開発ノウハウ、エンジニアキャリアについてのイベントを開催!アプリ開発を学ぶための勉強会を定期開催しています。
学習する習慣を身につけたい、他の参加者と作業したい、アプリ開発の基本をマスターしたい、という方のために無料で学べる勉強会です。
グループにメンバー登録して頂くと、イベント開催時にメールで通知されます。
 グループのメンバーとして参加する
徹底した基礎学習からのマスターするiPhoneアプリ開発集中オンライン講座開講!
徹底した基礎学習からのマスターするiPhoneアプリ開発集中オンライン講座開講!
本書「iPhoneアプリ開発集中講座」を執筆している現役エンジニア講師陣が直接に指導!
基礎、課題実習で実践力を鍛えて、オリジナルアプリ公開までチャレンジ!
充実した転職支援もあるので、エンジニアへ転職したい人にもおすすめです!
まずは、現役エンジニアに相談できる無料相談をご利用ください。