質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

5387閲覧

Swift シングルトンによる実装 v.s. static変数/メソッドによる実装

_WY_

総合スコア7

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

1クリップ

投稿2017/10/30 07:05

編集2017/10/30 16:44

iOSアプリを開発している者です。アプリ全体で用いるような値やメソッドを1つの構造体にまとめようとしており、以下の2パターンの実装を考えたのですが、どちらを採用するか決めかねています。

  • シングルトンを用いた実装
  • staticな変数/メソッドを用いた実装

以下に具体的なコードを記載します。例として、アプリで用いる色をまとめるColor構造体を実装してみました。


  • シングルトンを用いた実装

swift

1struct Color { 2 private init() {} 3 static let shared = Color() // シングルトン 4 5 // インスタンス変数 6 let gray: UIColor = UIColor(white: 0.5, alpha: 1.0) 7 8 // インスタンスメソッド 9 func someMethod() { 10 print("何かする") 11 } 12} 13 14// 利用時 15view.backgroundColor = Color.shared.gray 16Color.shared.someMethod()
  • staticな変数/メソッドを用いた実装

swift

1struct Color { 2 private init() {} // (2017.10.31 追記: インスタンス化できないよう修正しました) 3 4 // クラス変数 5 static let gray: UIColor = UIColor(white: 0.5, alpha: 1.0) 6 7 // クラスメソッド 8 static func someMethod() { 9 print("何かする") 10 } 11} 12 13// 利用時 14view.backgroundColor = Color.gray 15Color.someMethod()

今回お聞きしたいのは色の管理方法ではなく、上記2つの実装方法の違いやメリット/デメリットについてです。コーディングスタイルや設計思想、実行時のメモリや速度など、様々な観点からの比較・アドバイスを頂けますと幸いです。たくさんのご意見をお待ちしております。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

xAxis

2017/10/30 09:59

enumでも同じ機能実装出来そうですけどenumは無しです?
_WY_

2017/10/30 16:39

助言ありがとうございます!enumでも可能かと思いますが、ここでは2つの実装方法の違いやメリット/デメリットについて伺いたいです。
guest

回答1

0

ベストアンサー

とても面白いテーマですね。

どうなのでしょう。眺めてみていると、値の在り方的にはどちらも同じように感じつつ、その中でどこに違いが出てくるか、綴ってみようと思います。

Color インスタンスの有無(コスト性)

いちばん気になったのは Color 型のインスタンスが存在するかどうか に思いました。

シングルトンの場合、最初に Color のインスタンスを作成して、それが持つ UIColor のインスタンスを作成します。対して static の場合は UIColor のインスタンスだけで良くなるため、メモリー領域のコストが浮く…ように感じたのですが、構造体だと、どうなのでしょうね。

クラスの場合はポインター1つ分のメモリー領域が浮くと思うのですけど、構造体の場合はまるっとメモリーを取得するため、もしかすると領域的な差はないかもしれません。

そうなるとせいぜい Colorイニシャライザーが走るかどうか といったちょっとしたコストが増える程度かもしれません。

Color インスタンスの有無(コスト性・その2)

あと、これは自信がないのですけど static 宣言をした変数は、コンパイル時に全ての領域が(場所だけ)確保されるかもしれません。そうした場合、もしも Color を1回も使わなかった場合、その分のメモリーが無駄になる…かもしれません。

ただ、仮にそうなったとしても、無視できる程度のような気もしますけれど。

Color インスタンスの有無(共有性)

もうひとつ気になったのは Color そのもののインスタンスを扱えるかどうか です。これは、今回の例なら例えば "カラーテーマ" みたいな意味合いで扱おうとした場合、Color インスタンスがあれば、何か別の関数などに まるっと渡す ことができます。

static 変数の場合は、必要なインスタンスをひとつずつ渡すか、Color のメタタイプを渡す必要が出てきそうです。メタタイプを渡せば済む話でもありますけど、そんなあたりに違いが生まれて来そうです。

初期化のタイミング

あとは初期化のタイミングが気になりました。Swift の static 変数は lazy 変数と同じタイミング、つまり 初めて参照したタイミングにイニシャライザーが走る ようになっているので、色ごとに static 変数にしていた場合は、その色が使われたときに初めて、それだけの初期化コストが発生します。

対して、今回のシングルトンの例の場合、Color 変数は通常の let で色を持ってますので、全ての色が初期化されることになると思います。UIColor なら初期化コストも大したことないと思いますけど、初期化コストの高いものを扱う時には気にする必要が出てくることも、もしかするとあるかもしれません。

投稿2017/11/04 12:56

TomohiroKumagai

総合スコア441

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

_WY_

2017/11/04 18:34

ご回答ありがとうございます! なるほど、コスト面ではほとんど差がなさそうなのですね。また、関数にインスタンスを渡したい場面があるかどうかというのは盲点でした。加えて、static変数の初期化されるタイミングがlazyと同様であるというのも恥ずかしながら知りませんでした。勉強になりました。 ご回答を踏まえて、 ・インスタンスを扱いたい場面が出てくればシングルトン ・そうでなければ(単に利用時のコードを短くできるので)static といった使い分けにしようと思います。 様々な観点からのご回答を頂きすごく為になりました、ありがとうございました!ベストアンサーとさせて頂きます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問