Swiftで、class、staticキーワードの使い分けについて
Swiftで、class、static両者をどういったシーンで使いわけるか。
静的なアクセスを提供
いずれも使用することで静的にアクセス可能な変数/メソッドの宣言ができます。
// インスタンス化せずアクセスできる。静的な変数・メソッド。定数、ユーティリティメソッドの宣言に使用されることが多いと思います。 Some.somePropery Some.someMethod()
classとstaticメンバは相互呼び出しが可能で、その性質からいずれも静的にアクセスやデータが確保されていることがわかります。 機能の違いについては、こちらの記事が参考になります。
【Swift】classとstaticの挙動の違いを整理する - Qiita
どんな時に使えるか
staticキーワード
(1)enum、struct、classで「静的なプロパティ」「静的なメソッド」を宣言したい場合に使える。
(2)宣言したもののoverrideは出来ない。
classキーワード
(1)classで「静的なプロパティ(Computed Propertyのみ)」「静的なメソッド」を宣言したい場合に使える。enum、structでは使えない。
(2)finalと合わせて、宣言したもののoverrideの可否が制御出来る。
どう使い分けるか
ベースクラスにおけるstatic funcと、final class funcは機能的に同じことから、
・enum/structではstaticを使う。
・classでも基本的にstaticを使い、overrideが必要な変数/メソッドの場合にのみclassに変更する。
で良さそうです。
stackoverflowでの議論も参考になりました。
Static vs class functions/variables in Swift classes? - Stack Overflow
Swift3 / Swift2 「型の比較」「型名の取得」まとめメモ
Swiftのバージョン違い情報など、うまく検索に出なかったりしたのでまとめておきます。
型の取得
クラスから型(Class)を取得
// Swift2以前、および Swift3(どちらも同じ) SomeClass.self
インスタンスから型(Class)を取得
// Swift2以前 someInstance.dynamicType // Swift3 type(of: someInstance)
型名の取得#
Stringのイニシャライザに取得したClassを引数として与えます。
// Swift2以前 let className = String(someInstance.dynamicType) または let className = NSStringFromClass(someInstance.dynamicType) // Swift3 let className = String(reflecting: type(of: someInstance)) または let className = NSStringFromClass(type(of: someInstance))
型の比較
ベースクラス一致
// Swift2以前、および Swift3(どちらも同じ) if someInstance is HogeClass { // someInstanceがHogeClassを継承しているインスタンスだとtrue }
サブクラスまで完全一致
// Swift2.x以前 if someInstance.dynamicType === SubClass.self { // someInstanceがSubClassと同じ型だとtrue } // Swift3 if type(of: someInstance) === SubClass.self { // someInstanceがSubClassと同じ型だとtrue }
上記では、===を使用していますが、==でも実行したところ問題が無さそうです。
参考: How to check two instances are the same class/type in swift - Stack Overflow
<補足>
===、!==(トリプルイコール)演算子
a === b でaとbが同じオブジェクト(インスタンス)であることを確認できる。
==、!=(ダブルイコール)演算子
a==b が同じ値であることを確認できる。
is演算子
型チェック(目的のクラスを継承しているか)