Codable Tech Blog

iPhoneアプリケーション開発と AWS(Amazon Web Service)活用に関する記事を配信

プロパティ(ストアドプロパティとコンピューテッドプロパティ)

Swiftではプロパティとしてストアドプロパティ(Stored Property)とコンピューテッド・プロパティ(Computed Property)が用意されています。以降ではこれらのプロパティに関する説明を行います。

ストアドプロパティ(Stored Property)

ストアドプロパティ(Stored Property)はクラスの一部として定義された値を格納する変数・定数になります。ストアドプロパティの宣言は次のようになります。

class クラス名{
    var プロパティ名 =let プロパティ名 = 値
}

クラスでストアドプロパティを定義する時は、デフォルト値を与える必要があります。もし、デフォルト値を与えない場合、「initメソッドを定義して初期化してください」という旨のコンパイルエラーが発生します。次の例ではPersonクラスにストアドプロパティ(Stored Property)としてfirstNameとlastName、ageを定義した例です。

上記の例では、デフォルト値としてfirstNameとlastNameに""を与え、ageに0を与えて初期化しています。
initメソッドを実装してストアドプロパティを初期化したい場合は次のようにします。

この場合は、ストアドプロパティにデフォルト値を設定しなくても、コンパイルエラーにはなりません。

プロパティ監視

Swiftではストアドプロパティ(Stored Property)の値が変更されたタイミングを監視する仕組みがあります。この仕組みはプロパティ監視と呼ばれています。プロパティ監視を利用したい場合、次の2つのメソッドのいずれか、あるいは両方を実装します。

willSet(パラメータ名) 値が格納される直前に呼ばれるメソッド
didSet(パラメータ名) 値が格納された直後に呼ばれるメソッド

上記の2つのメソッドを定義したクラスの構文は次のようになります。

var プロパティ名:型{
    willSet(パラメータ名) {
        文
        return 値
    }
    didSet(パラメータ名) {
        文
    }
}

willSetメソッドのパラメータには呼び出し元から渡された値、didSetメソッドのパラメータには変更前のプロパティの値が定数で渡されます。なお、パラメータ名を指定せずにwillSet、didSetメソッドを定義した場合、パラメータ名newValueという名前の定数が自動で生成されます。なお、どちらのメソッドの初期化処理の時は呼び出されません。次の例ではPersonクラスのプロパティageの値を監視するために、willSetメソッドとdidSetメソッドを実装しています。

ageプロパティの値を変更するタイミングでwillSetメソッドとdidSetメソッドが呼び出されていることが確認できます。willSetメソッドのパラメータには呼び出し元から渡された値が代入されているのでvalueの値は10になります。didSetメソッドのパラメータには変更前のプロパティの値が代入されていますのでvalueの値は0になります。

コンピューテッド・プロパティ(Computed Property)

コンピューテッド・プロパティ(Computed Property)はゲッターメソッドとセッターメソッドと呼ばれる2つのメソッドを提供するプロパティです。値を返すメソッドをゲッターメソッド、値を設定するメソッドのことをセッターメソッドと呼びます。コンピューテッド・プロパティ(Computed Property)は次のような構文で定義できます。

var プロパティ名:型{
    get {
        文
        return 値
    }
    set(パラメータ) {
        文
    }
}

getメソッドはプロパティにアクセスする時、setメソッドはプロパティに対して値の代入操作を行った時にそれぞれ呼ばれます。setメソッドのパラメータには代入したい値が設定されます。次の例ではPersonクラスにfullNameというコンピューテッド・プロパティ(Computed Property)を追加しています。

getメソッドではストアドプロパティ(Stored Property)のfirstNameとlastNameを連結した文字列を返却しています。setメソッドはパラメータnameの値をスペース区切りで分割して、firstNameとlastNameに代入しています。

コンピューテッド・プロパティ(Computed Property)へのアクセス

コンピューテッド・プロパティ(Computed Property)もドット構文を利用してアクセスできます。次の構文でコンピューテッド・プロパティ(Computed Property)にアクセスしたときにはプロパティのgetメソッドが動作します。

インスタンス名.プロパティ名

また、次の構文でコンピューテッド・プロパティ(Computed Property)に代入操作を行った時ににプロパティのsetメソッドが動作します。

インスタンス名.プロパティ名 =

次の例は、ドット構文を使用してPersonのインスタンスであるpersonからプロパティfullNameにアクセスしています。

ドット構文を利用してfullNameにアクセスすると、fullNameのgetメソッドが呼ばれます。getメソッドが呼ばれるとfistNameとlastNameの値を連結した文字列が返却されます。また、fullNameプロパティに対して値の代入処理を行うとsetメソッドが呼ばれます。スペース区切りの名前「Taro Yamada」を代入すると、まず、setメソッドのnameパラメータにTaro Yamadaが代入されます。setメソッドではnameパラメータの値をスペース区切りで分割していますので、firstNameにはTaro lastNameにはYamadaが代入されます。

コンピューテッド・プロパティ(Computed Property)のセッターパラメータの省略

コンピューテッド・プロパティではセッターのパラメータを省略して、次のように記述することもできます。

var プロパティ名:型{
    get {
        文
        return 値
    }
    set {
        文
    }
}

このように定義した場合、呼び出し元から渡された値はnewValueという名前の変数に渡されます。先ほど、PersonクラスのプロパティfullNameをパラメータを省略する形で定義した場合、次のようになります。

読み取りのみのコンピューテッド・プロパティ(Computed Property)

ピューテッド・プロパティはセッターはサポートせず、ゲッターのみをサポートするように定義することができます。ゲッターのみをサポートしたい場合、次のような構文で定義します。

var プロパティ名:型{
        文
        return 値
    }
}

このように定義することでゲッターのみをサポートするコンピューテッド・プロパティ(Computed Property)を定義することができます。次の例はPersonクラスに成人かどうかを判定するadultプロパティを読み取りのみで定義した例です。

補足

遅延ストアドプロパティ(lazy Stored Properties)

遅延ストアドプロパティはそのプロパティが最初に利用されるときまで初期値が設定されないプロパティです。プロパティの宣言時にlazyキーワードを置くことで遅延ストアドプロパティであることを宣言できます。遅延ストアドプロパティは次のような構文になります。

class クラス名 {
    lazy プロパティ名 = 値
}

遅延ストアドプロパティは、インスタンス生成時そのプロパティを必要せず、かつ、プロパティの初期化処理に時間を多く割いてしまう場合に役立ちます。次の例は遅延ストアドプロパティを利用したPersonクラスの例です。

この例ではNetDataプロパティにlazyキーワードが指定されています。この場合、15行目でpersonクラスのインスタンスを生成していますが、netDataプロパティの値は未確定の状態でインスタンスが生成されます。そして、21行目で実際にデータが必要になったタイミングでインターネット上からデータをダウンロードする処理を実行させます。このように、データが必要になるまで処理を遅延させることでユーザーにとって使い勝手の良いアプリケーションを作成することが可能になります。