var
キーワードを使用)または定数格納プロパティ(let
キーワードを使用) のいずれかです。FixedLengthRange
という構造体を定義しています。これは、作成後に範囲の長さを変更できない整数の範囲を表します。FixedLengthRange
のインスタンスには、firstValue
と呼ばれる変数格納プロパティと length
という定数格納プロパティがあります。上記の例では、定数のため、長さは新しい範囲が作成されたときに初期化され、それ以降は変更できません。rangeOfFourItems
は定数として(let
キーワードを使用して)宣言されているため、firstValue
が変数でも、その firstValue
プロパティを変更することはできません。lazy
修飾子を記述して、遅延格納プロパティを示します。NOTE インスタンスの初期化が完了するまで初期値が取得できない可能性があるため、遅延プロパティは常に変数として(var
キーワードを使用して)宣言する必要があります。定数プロパティは、初期化が完了する前に常に値を持っている必要があるため、lazy
で宣言することはできません。
DataImporter
と DataManager
という 2 つのクラスを定義していますが、どちらも全体像は表示していません:DataManager
クラスには、data
と呼ばれる格納プロパティがあり、新しい空の String
型の配列で初期化されています。残りの機能は示されていませんが、この DataManager
クラスの目的は、この String
の配列を管理し、アクセスする機能を提供することです。DataManager
クラスの機能の一部は、ファイルからデータをインポートする機能です。この機能は、DataImporter
クラスによって提供されています。このクラスは、初期化にかなりの時間がかかると想定されています。これは、DataImporter
インスタンスが初期化されるときに、ファイルを開いてその内容をメモリに読み込む必要があるため時間がかかる可能性があります。DataManager
インスタンスはファイルからデータをインポートしなくてもデータを管理できるため、DataManager
自体が作成されるときに、DataManager
は新しい DataImporter
インスタンスを作成しません。代わりに、DataImporter
インスタンスを最初に使用するときに作成する方が理にかなっています。lazy
修飾子でマークされているため、importer
プロパティの DataImporter
インスタンスは、importer
プロパティが最初にアクセスされたとき(filename
プロパティが照会されたときなど)にのみ作成されます。NOTElazy
修飾子でマークされたプロパティが複数のスレッドから同時にアクセスされ、そのプロパティがまだ初期化されていない場合、そのプロパティが 1 回だけ初期化されるという保証はありません。
Objective-C
の経験がある場合は、クラスインスタンスの一部として値と参照を格納する 2 つの方法が提供されていることを知っているかもしれません。プロパティに加えて、インスタンス変数をプロパティに格納されている値のバッキングストアとして使用できます。Point
は、x 座標と y 座標をカプセル化していますSize
は width
と height
をカプセル化していますRect
は、原点とサイズで四角形を定義していますRect
構造体は、center
と呼ばれる計算プロパティも提供します。Rect
の現在の中心位置は常にその origin
と size
から判断できるため、中心点を明示的に Point
として保存する必要はありません。代わりに、Rect
は center
と呼ばれる計算プロパティ変数の独自の get/set を定義して、あたかも格納プロパティかのように四角形の中心を操作できるようにします。square
という新しい Rect
変数を作成しています。square
変数は、原点 (0, 0)
、幅と高さ 10
で初期化されます。この正方形は、下の図では青い正方形で表されています。square.center
)を介して Square
変数の center
プロパティにアクセスします。これにより、center
の get が呼び出され、現在のプロパティ値が取得できます。get は、既存の値を返すのではなく、正方形の中心を表す新しい Point
を計算して返します。上記のように、get は (5, 5)
の中心点を正しく返します。center
プロパティに新しく (15, 15)
が設定されます。これにより、下の図のオレンジ色の正方形で示されている新しい位置に正方形が上下に移動します。center
プロパティを設定すると、保存されている origin
プロパティの x
と y
の値を変更する center
の set が呼び出され、正方形が新しい位置に移動します。newValue
が使用されます。下記はこの省略表記を利用した Rect
構造体の代替バージョンを次に示します:Rect
構造体を次に示します:NOTE (読み取り専用を含む)計算プロパティは、その値が固定されていないため、var
キーワードを使用して変数プロパティとして宣言する必要があります。let
キーワードは定数プロパティにのみ使用され、インスタンスの初期化の一部として設定された後は値を変更できないことを示します。
get
キーワードとその中括弧({}
)を削除することで、読み取り専用計算プロパティの宣言を簡素化できます。Cuboid
という新しい構造体を定義します。これは、width
、height
、depth
プロパティを持つ 3D の長方形のボックスを表します。この構造体には、volume
と呼ばれる読み取り専用計算プロパティもあります。これは、直方体の現在のボリュームを計算して返します。特定のボリューム値に width
、height
、depth
のどの値が使用されているかがあいまいなため、volume
に set 可能にすることは意味がありません。それでも、Cuboid
が読み取り専用計算プロパティを提供して、外部ユーザーが現在の計算済みボリュームを見られようにすると便利です。willSet
は、値が格納される直前に呼び出されますdidSet
は、新しい値が格納された直後に呼び出されますwillSet
オブザーバを実装すると、新しいプロパティ値が定数パラメータとして渡されます。willSet
実装の一部として、このパラメータの名前を指定できます。実装内にパラメータ名と括弧を記述しない場合、パラメータは newValue
というのデフォルトのパラメータ名で使用可能になります。didSet
オブザーバを実装する場合、古いプロパティ値を含む定数パラメータが渡されます。パラメータに名前を付けるか、oldValue
というデフォルトパラメータ名を使用できます。独自の didSet
オブザーバ内のプロパティに値を割り当てると、新しい値によって、設定されたばかりの値が置き換えられます。NOTE スーパークラスのプロパティのwillSet
およびdidSet
オブザーバは、プロパティがサブクラスのイニシャライザで設定されると、スーパークラスのイニシャライザが呼び出された後に呼び出されます。スーパークラスのイニシャライザが呼び出される前に、サブクラスが独自のプロパティを設定している間は呼び出されません。 イニシャライザの委譲については、Initializer Delegation for Value Types(値型のイニシャライザの委譲)、Initializer Delegation for Class Types(クラス型のイニシャライザの委譲)を参照ください。
willSet
と didSet
の使用例を次に示します。下記の例では、StepCounter
という名前の新しいクラスを定義しています。これは、人の合計歩数を追跡します。このクラスは、万歩計からの入力データやその他の日常生活での運動を追跡する歩数計に使われます。StepCounter
クラスは、Int
型の totalSteps
プロパティを宣言します。これは、willSet
および didSet
オブザーバを持つ格納プロパティです。totalSteps
の willSet
および didSet
オブザーバが呼び出されます。これは、新しい値が現在の値と同じでも呼び出されます。willSet
オブザーバは、次の新しい値に newTotalSteps
のカスタムパラメータ名を使用します。この例では、設定しようとしている値を出力するだけです。didSet
オブザーバは、totalSteps
の値が更新された後に呼び出されます。これは、totalSteps
の新しい値を古い値と比較します。合計ステップ数が増えると、新しく何ステップ増えたかを示すメッセージが出力されます。didSet
オブザーバは古い値のカスタムパラメータ名を提供せず、代わりに oldValue
のデフォルト名が使用されます。NOTE オブザーバを持つプロパティを関数に入出力パラメータとして渡すと、willSet
およびdidSet
オブザーバが常に呼び出されます。これは、入出力パラメータのコピーインコピーアウト(copy-in copy-out)メモリモデルによるものです。値は常に関数の最後でプロパティに書き戻されます。入出力パラメータの動作の詳細については、In-Out Parameters(In-Out パラメータ)を参照ください。
wrappedValue
プロパティを定義する構造体、列挙型、またはクラスを作成します。下記のコードでは、TwelveOrLess
構造体により、ラップする値に常に 12
以下の数値が含まれることが保証されます。より大きな数値を格納するように要求すると、代わりに 12
が格納されます。12
未満だと確認し、get は格納された値を返します。NOTE 上記の例のnumber
の宣言は、変数をprivate
としてマークします。これにより、number
はTwelveOrLess
の実装でのみ使用されます。それ以外の場所に記述されたコードは、wrappedValue
のプロパティの get/set を通して値にアクセスし、数値を直接使用することはできません。private
については、Access Control(アクセスコントロール)を参照ください。
TwelveOrLess
プロパティラッパを使用して、大きさが常に 12
以下になるようにする四角形を格納する構造体を次に示します。height
と width
のプロパティは、TwelveOrLess.number
を 0 に設定する TwelveOrLess
の定義から初期値を取得します。TwelveOrLess
の set は、10
を有効な値として扱うため、数値 10
を rectangle.height
に格納すると、記述どおりに進みます。ただし、24
は TwelveOrLess
が許容する値よりも大きいため、24
を格納しようとすると、代わりに rectangle.height
を最大許容値の 12
に設定することになります。SmallRectangle
に、属性として @TwelveOrLess
を記述する代わりに、TwelveOrLess
構造体でそのプロパティを明示的にラップしています。_height
および _width
プロパティは、プロパティラッパ TwelveOrLess
のインスタンスを格納します。height
と width
の get/set は、wrappedValue
プロパティへのアクセスをラップします。TwelveOrLess
の定義で number
に初期値を与えることにより、ラップされたプロパティの初期値を設定します。このプロパティラッパを使用するコードでは、TwelveOrLess
でラップされたプロパティに異なる初期値を指定できません。例えば、SmallRectangle
の定義では height
や width
の初期値を指定できません。初期値の設定やその他のカスタマイズをサポートするには、プロパティラッパでイニシャライザを追加する必要があります。これは、ラップされた値と最大値を設定するイニシャライザを定義する SmallNumber
と呼ばれる TwelveOrLess
の拡張バージョンです。SmallNumber
の定義には、init()
、init(wrappedValue:)
、および init(wrappedValue:maximum:)
の 3 つのイニシャライザが含まれています。下記の例では、これらのイニシャライザを使用して、ラップされた値と最大値を設定します。イニシャライザとその構文については、Initialization(初期化)を参照ください。init()
を使用してラッパを設定します。例えば:height
と width
をラップする SmallNumber
のインスタンスは、SmallNumber()
を呼び出すことによって作成されます。そのイニシャライザ内のコードは、0 と 12 のデフォルト値を使用して、ラップされた値の初期値と最大値の初期値を設定します。プロパティラッパは、SmallRectangle
で TwelveOrLess
を使用した前の例のように、引き続き全ての初期値を設定します。その例とは異なり、SmallNumber
は、プロパティの宣言の一部としてこれらの初期値を書き込むこともサポートしています。init(wrappedValue:)
イニシャライザを使用してラッパを設定します。例えば:= 1
を書き込むと、それは init(wrappedValue:)
イニシャライザの呼び出しに変換されます。height
と width
をラップする SmallNumber
のインスタンスは、SmallNumber(wrappedValue: 1)
を呼び出すことによって作成されます。イニシャライザは、ここで指定されたラップされた値を使用し、デフォルトの最大値の 12
を使用します。init(wrappedValue:maximum:)
イニシャライザを使用します:height
をラップする SmallNumber
のインスタンスは SmallNumber(wrappedValue: 2, maximum: 5)
を呼び出すことで作成され、width
をラップするインスタンスは SmallNumber(wrappedValue: 3, maximum: 4)
を呼び出すことで作成されます。wrappedValue
引数のように扱い、含まれる引数を受け入れるイニシャライザを使用します。例えば:height
をラップする SmallNumber
のインスタンスは、デフォルトの最大値 12 を使用する SmallNumber(wrappedValue: 1)
を呼び出すことによって作成されます。width
をラップするインスタンスは、SmallNumber(wrappedValue: 2, maximum: 9)
を呼び出すことによって作成されます。flushDatabaseConnection()
メソッドを提供できます。projectedValue の名前は、ドル記号 ($
) で始まることを除いて、ラップされた値と同じです。コードでは $
で始まるプロパティを定義できないため、projectedValue が定義したプロパティにコードから干渉することはありません。SmallNumber
の例では、プロパティを大きすぎる数値に設定しようとすると、プロパティラッパは数値を格納する前に調整します。下記のコードは、projectedValue
プロパティを SmallNumber
構造体に追加して、プロパティラッパが新しい値を格納する前にプロパティの新しい値を調整したかどうかを追跡します。someStructure.$someNumber
を書き込むと、ラッパの projectedValue にアクセスします。4 などの小さな数を格納した後、someStructure.$someNumber
の値は false
です。ただし、55 などの大きすぎる数値を格納しようとすると、projectedValue は true
になります。self
を返してラッパのインスタンスをその projectedValue として公開することもできます。self.
を省略できます。次の例のコードは、height
と width
のラッパの projectedValue を $height
および $width
として参照します。height
と width
へのアクセスは、他のプロパティへのアクセスと同じように働きます。例えば、resize(to:)
のコードは、プロパティラッパを使用して height
と width
にアクセスします。resize(to: .large)
を呼び出すと、.large
の switch の case により、長方形の高さと幅が 100 に設定されます。ラッパはそれぞれのプロパティが 12 を超えないようにするため、値を調整したことを記録し、projectedValue に true
が設定されます。resize(to:)
の最後で、return
ステートメントは $height
と $width
をチェックして、プロパティラッパが height
または width
のいずれかを調整したかどうかを判断します。NOTE グローバル定数と変数は、遅延格納プロパティと同様の方法で、常に必要なったら計算されます。遅延格納プロパティとは異なり、グローバル定数と変数はlazy
修飾子でマークする必要はありません。 ローカル定数と変数は決して遅延して計算されません。
myNumber
は SmallNumber
をプロパティラッパとして使用します。myNumber
を 10 に設定することは有効です。プロパティラッパは 12 を超える値を許可しないため、myNumber
を 24 ではなく 12 に設定します。NOTE 格納インスタンスプロパティとは異なり、格納型プロパティには常にデフォルト値を指定する必要があります。これは、型の初期化時に格納型プロパティに値を割り当てることができるイニシャライザがないためです。 格納型プロパティは、最初のアクセス時に遅延して初期化されます。それらは、複数のスレッドから同時にアクセスされた場合でも、1 回だけ初期化されることが保証されており、lazy
修飾子でマークする必要はありません。
{}
)に記述され、各型プロパティは、サポートする型に明示的にスコープされます。static
キーワードを使用して型プロパティを定義します。クラス型の計算型プロパティの場合、代わりに class
キーワードを使用して、サブクラスがスーパークラスの実装をオーバーライドできるようにすることもできます。下記の例は、格納および計算型プロパティの構文を示しています。NOTE 上記の計算型プロパティの例は、読み取り専用の計算型プロパティですが、計算インスタンスプロパティと同じ構文を使用して、読み書き可能な計算型プロパティを定義することもできます。
0
から 10
までの整数のオーディオレベルがあります。0
の場合、そのチャンネルのライトはどれも点灯しません。オーディオレベルが 10
の場合、そのチャンネルの全てのライトが点灯します。この図では、左チャネルの現在のレベルは 9
で、右チャネルの現在のレベルは 7
です。AudioChannel
構造体のインスタンスによって表されます。AudioChannel
構造体は、その機能をサポートする 2 つの格納型プロパティを定義します。最初の thresholdLevel
は、オーディオレベルの最大のしきい値を定義します。これは、全ての AudioChannel
インスタンスの定数値 10
です。オーディオ信号が 10
よりも高い値で入力されると、このしきい値に制限されます (後述)。maxInputLevelForAllChannels
と呼ばれる変数格納型プロパティです。これは、AudioChannel
インスタンスによって受信された最大入力値を追跡します。初期値 0
から始まります。AudioChannel
構造体は、0
から 10
のスケールでチャネルの現在のオーディオレベルを表す、currentLevel
と呼ばれる保存されたインスタンスプロパティも定義します。currentLevel
プロパティには、設定されるたびに currentLevel
の値をチェックする didSet
プロパティオブザーバがあります。このオブザーバは、次の 2 つのチェックを実行します:currentLevel
の新しい値が許可された thresholdLevel
より大きい場合、プロパティオブザーバは currentLevel
を thresholdLevel
に制限しますcurrentLevel
の新しい値が、AudioChannel
インスタンスによって以前に受信された値よりも大きい場合、プロパティオブザーバは新しい currentLevel
値を maxInputLevelForAllChannels
型プロパティに保存しますNOTE これらの 2 つのチェックのうち最初のチェックでは、didSet
オブザーバはcurrentLevel
を別の値に設定します。ただし、これによってオブザーバが再度呼び出されることはありません。
AudioChannel
構造体を使用して、ステレオサウンドシステムのオーディオレベルを表す、leftChannel
および rightChannel
という 2 つの新しいオーディオチャネルを作成できます。currentLevel
を 7
に設定すると、maxInputLevelForAllChannels
型プロパティが 7
に更新されることがわかります。currentLevel
を 11
に設定しようとすると、右チャネルの currentLevel
プロパティが最大値 10
に制限され、maxInputLevelForAllChannels
型プロパティが 10
に更新されることがわかります。