インスタンスプロパティは、特定の型のインスタンスに属するプロパティです。その型のインスタンスを生成するたびに、そのインスタンス専用のプロパティ値セットができ、他のインスタンスから切り離されています。

型のあるインスタンスにではなく、その型自身に属するプロパティを定義することもできます。その型のインスタンスをどれほどたくさん生成したとしても、これらのプロパティのコピーは 1 つだけになります。このようなプロパティのことをタイププロパティと呼びます。

タイププロパティは、すべてのインスタンスが利用できる(C の static 定数のような)定数プロパティ、あるいは特定の型のすべてのインスタンスにグローバルな値を保管する(C の static 変数のような)変数プロパティのように、その型のすべてのインスタンスに共通の値を定義するのに役に立ちます。

ストアドタイププロパティは、変数にも定数にもできます。コンピューテッドタイププロパティは常に、コンピューテッドインスタンスプロパティと同じように変数プロパティとして宣言されます。

NOTE

ストアドインスタンスプロパティと違い、ストアドタイププロパティにはデフォルト値が必要です。これは、初期化時にストアドタイププロパティに値を代入できるイニシャライザを、型自身が持っていないためです。

ストアドタイププロパティは、遅延して最初のアクセス時に初期化されます。複数のスレッドから同時にアクセスされた場合でも、一回だけ初期化されることが保証されており、lazy を付ける必要はありません。

タイププロパティシンタックス

C と Objective-C では、グローバルな static 変数として型に関連した static 定数と static 変数を定義します。一方 Swift では、タイププロパティは型の定義の一部として、型の外側の波括弧内に記述され、各タイププロパティは明確にサポートする型のスコープとなります。

static キーワードでタイププロパティを定義します。クラスのコンピューテッドタイププロパティには、スーパークラスの実装をサブクラスがオーバーライドできるように、class キーワードを代わりに利用することができます。次の例は、ストアドとコンピューテッドのタイププロパティを示しています。

struct SomeStructure {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 1
    }
}
enum SomeEnumeration {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 6
    }
}
class SomeClass {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 27
    }
    class var overrideableComputedTypeProperty: Int {
        return 107
    }
}
NOTE
上のコンピューテッドタイププロパティの例は、読み取り専用のコンピューテッドタイププロパティですが、コンピューテッドインスタンスプロパティと同じシンタックスで、読み書き可能なコンピューテッドタイププロパティを定義することも可能です。

タイププロパティにアクセス

タイププロパティには、インスタンスプロパティと同じように、ドットシンタックスでアクセスします。ですが、タイププロパティは型のインスタンスにではなく、その型に対してアクセスします。

print(SomeStructure.storedTypeProperty)
// "Some value." と出力
SomeStructure.storedTypeProperty = "Another value."
print(SomeStructure.storedTypeProperty)
// "Another value." と出力
print(SomeEnumeration.computedTypeProperty)
// "6" と出力
print(SomeClass.computedTypeProperty)
// "27" と出力

次の例では、音声チャンネル数のオーディオレベルメーターをモデル化した構造体の一部として、2 つのストアドタイププロパティを使用しています。各チャンネルには、整数 0 から 10 までのオーディオレベルがあります。

次の図では、ステレオオーディオレベルメーターをモデル化するために、2 つの音声チャンネルを組み合わせています。チャンネルのオーディオレベルが 0 のとき、そのチャンネルのライトは光りません。オーディオレベルが 10 のときには、そのチャンネルのすべてのライトが光ります。この図では、左のチャンネルがレベル 9 で、右のチャンネルがレベル 7 です。

image: staticPropertiesVUMeter_2x

この音声チャンネルを、構造体 AudioChannel のインスタンスで表現しています。

struct AudioChannel {
    static let thresholdLevel = 10
    static var maxInputLevelForAllChannels = 0
    var currentLevel: Int = 0 {
        didSet {
            if currentLevel > AudioChannel.thresholdLevel {
                // 新しいオーディオレベルの上限を thresholdLevel とする
                currentLevel = AudioChannel.thresholdLevel
            }
            if currentLevel > AudioChannel.maxInputLevelForAllChannels {
                // 全体の最大入力レベルとして保存する
                AudioChannel.maxInputLevelForAllChannels = currentLevel
            }
        }
    }
}

構造体 AudioChannel は、機能をサポートする 2 つのストアドタイププロパティを定義しています。1 つ目は thresholdLevel で、オーディオレベルの最大限界値を定義しています。すべての AudioChannel インスタンスにとっての定数値で 10 です。音声信号が 10 よりも高い値となった場合、(以下で説明しているように)この限界値で制限されます。

2 つ目のタイププロパティは、変数ストアドプロパティ maxInputLevelForAllChannels です。あらゆる AudioChannel インスタンスが受け取った最大入力値を記録します。初期値 0 で開始します。

構造体 AudioChannel は、チャンネルの現在のオーディオレベルを 0 から 10 までで表すストアドインスタンスプロパティ currentLevel も定義しています。

currentLevel プロパティには、currentLevel の値が設定されたことを監視するプロパティオブザーバ didSet があります。このオブザーバは 2 つのチェックを実施します。

  • currentLevel の新しい値が thresholdLevel よりも大きい場合、プロパティオブザーバは currentLevel の上限を thresholdLevel とする。
  • currentLevel の(上限適用後の)新しい値が、あらゆる AudioChannel インスタンスが以前に受け取ったどの値よりも大きい場合、プロパティオブザーバは新しい currentLevel 値をタイププロパティ maxInputLevelForAllChannels に保管します。
NOTE
2 つのチェックの 1 つ目で、didSet オブサーバが currentLevel に異なる値を設定しています。ですが、このことによってオブザーバがあらためて呼び出されることはありません。

ステレオ音声システムのオーディオレベルを表す 2 つのオーディオチャンネル leftChannel と rightChannel を生成するために、構造体 AudioChannel を使うことができます。

var leftChannel = AudioChannel()
var rightChannel = AudioChannel()

左チャンネルの currentLevel に 7 を設定した場合、タイププロパティ maxInputLevelForAllChannels は 7 に更新されます。

leftChannel.currentLevel = 7
print(leftChannel.currentLevel)
// "7" と出力
print(AudioChannel.maxInputLevelForAllChannels)
// "7" と出力

右チャンネルの currentLevel に 11 を設定しようとした場合、右チャンネルの currentLevel プロパティは最大値 10 を上限に制限され、タイププロパティ maxInputLevelForAllChannels は 10 に更新されます。

rightChannel.currentLevel = 11
print(rightChannel.currentLevel)
// "10" と出力
print(AudioChannel.maxInputLevelForAllChannels)
// "10" と出力

Portions of this page are translations based on work created and shared by Apple and used according to terms described in the Creative Commons Attribution 4.0 International License.