インスタンスプロパティは、特定の型のインスタンスに属するプロパティです。その型のインスタンスを生成するたびに、そのインスタンス専用のプロパティ値セットができ、他のインスタンスから切り離されています。
型のあるインスタンスにではなく、その型自身に属するプロパティを定義することもできます。その型のインスタンスをどれほどたくさん生成したとしても、これらのプロパティのコピーは 1 つだけになります。このようなプロパティのことをタイププロパティと呼びます。
タイププロパティは、すべてのインスタンスが利用できる(C の static 定数のような)定数プロパティ、あるいは特定の型のすべてのインスタンスにグローバルな値を保管する(C の static 変数のような)変数プロパティのように、その型のすべてのインスタンスに共通の値を定義するのに役に立ちます。
ストアドタイププロパティは、変数にも定数にもできます。コンピューテッドタイププロパティは常に、コンピューテッドインスタンスプロパティと同じように変数プロパティとして宣言されます。
ストアドインスタンスプロパティと違い、ストアドタイププロパティにはデフォルト値が必要です。これは、初期化時にストアドタイププロパティに値を代入できるイニシャライザを、型自身が持っていないためです。
ストアドタイププロパティは、遅延して最初のアクセス時に初期化されます。複数のスレッドから同時にアクセスされた場合でも、一回だけ初期化されることが保証されており、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
}
}
タイププロパティにアクセス
タイププロパティには、インスタンスプロパティと同じように、ドットシンタックスでアクセスします。ですが、タイププロパティは型のインスタンスにではなく、その型に対してアクセスします。
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
です。
この音声チャンネルを、構造体 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
に保管します。
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.