Swift

【Swift入門】プロパティについてわかりやすく徹底解説!〜初心者でもわかるように解説します。〜

カズキ

今回はSwiftのプロパティについて初心者にも分かりやすいように解説していきたいと思います。

この記事を読むと、

・プロパティとは

・プロパティの種類

・ゲッタ、セッタとは

などを学ぶ事ができます。

ぜひ最後まで読んでいってください。

プロパティとは

Swiftのプロパティは、型(クラス、構造体、列挙型)を構成する要素の一つで、型もしくは型のインスタンスに紐付いた値を指します。

struct Programming {
    // これがプロパティ
    var language = "Swift"

    // これがメソッド
    func introduce() {
        print("This is \(self.language)")
    }
}

プロパティの種類

プロパティにはいくつか種類があり、そのプロパティが持つ特性によって分類されています。以下にプロパティの種類を挙げて、それぞれの性質について解説します。

ストアドプロパティ

Swiftのストアドプロパティは、値を保存するために使用されます。ストアドプロパティは、クラスや構造体の中でvarキーワードを使用して宣言されます。ストアドプロパティは、宣言された時点で初期値を持ち、変更することができます。

例:

class MyClass {
    var myProperty: Int = 0
}

let instance = MyClass()
print(instance.myProperty) // 0
instance.myProperty = 10
print(instance.myProperty) // 10

この例では、MyClassのインスタンスに対して、myPropertyというストアドプロパティが宣言されています。それはvarであり、初期値が0です。インスタンスを生成し、それにアクセスし、値を変更することができます。

また、

Swiftのストアドプロパティには、willSetとdidSetという2つのプロパティオブザーバーがあります。これらのプロパティオブザーバーは、特定の条件下でプロパティが変更される前後に実行される処理を指定するために使用されます。

  • willSet ストアドプロパティの値が変更される直前に呼び出されます。新しい値が渡されます。
  • didSet ストアドプロパティの値が変更された直後に呼び出されます。古い値が渡されます。

例:

class MyClass {
    var myProperty: Int = 0 {
        willSet(newValue) {
            print("willSet: \(newValue)")
        }
        didSet {
            print("didSet: \(oldValue)")
        }
    }
}

let instance = MyClass()
instance.myProperty = 10

// Output:
// willSet: 10
// didSet: 0

この例では、MyClassのインスタンスに対して、myPropertyというストアドプロパティが宣言され、willSetとdidSetのプロパティオブザーバーが設定されています。myPropertyが変更される直前にwillSetが呼び出され、変更後にdidSetが呼び出されます。 プロパティオブザーバーは、特定の条件下でプロパティが変更される前後に実行する処理を指定するために非常に便利で、変数の値の変更に応じて処理を実行するような場合に使用されます。

コンピューテッドプロパティ

Swiftのコンピューテッドプロパティは、値を計算するために使用されます。コンピューテッドプロパティは、クラスや構造体の中でvarまたはletキーワードを使用して宣言されます。コンピューテッドプロパティは、宣言された時点で初期値を持ちません。

例:

class MyClass {
    var myProperty: Int
    var myComputedProperty: Int {
        get {
            return myProperty * 2
        }
        set(newValue) {
            myProperty = newValue / 2
        }
    }
}

let instance = MyClass(myProperty: 5)
print(instance.myComputedProperty) // 10
instance.myComputedProperty = 20
print(instance.myProperty) // 10

この例では、MyClassのインスタンスに対して、myPropertyというストアドプロパティと、myComputedPropertyというコンピューテッドプロパティが宣言されています。myComputedPropertyは、myPropertyの値に対して2倍する計算を行っています。また、myComputedPropertyに新しい値を代入することで、myPropertyの値も変更されます。

コンピューテッドプロパティは、変数の値に応じて動的に値を返す、計算によって求められる値を表現するような場合に使用されます。

インスタンスプロパティ

Swiftのインスタンスプロパティは、特定のインスタンスに関連した値を保持するために使用されます。クラスや構造体のインスタンスが生成されると、それぞれが自身のインスタンスプロパティを持ちます。 インスタンスプロパティは、クラスや構造体の中で宣言されます。宣言するときには、varまたはletを使用して、それが変更可能なかどうかを指定します。

例:

class MyClass {
    var myProperty: Int = 0 
}

let instance = MyClass()
print(instance.myProperty) // 0
instance.myProperty = 10
print(instance.myProperty) // 10

この例では、MyClassのインスタンスに対して、myPropertyというインスタンスプロパティが宣言されています。それはvarであり、初期値が0です。インスタンスを生成し、それにアクセスし、値を変更することができます。

スタティックプロパティ

Swiftのスタティックプロパティは、クラスや構造体に関連した値を保持するために使用されます。スタティックプロパティは、クラスや構造体のインスタンスを生成することなくアクセスすることができます。スタティックプロパティは、クラスや構造体の中でstaticキーワードを使用して宣言されます。

例:

class MyClass {
    static var myProperty: Int = 0
}

print(MyClass.myProperty) // 0
MyClass.myProperty = 10
print(MyClass.myProperty) // 10

この例では、MyClassに対して、myPropertyというスタティックプロパティが宣言されています。それはstatic varであり、初期値が0です。インスタンスを生成することなく、それにアクセスし、値を変更することができます。 スタティックプロパティは、クラスの中でのみ宣言できますが、構造体についてもstaticプロパティを持つことができます。

クラスプロパティ

Swiftにおいてクラスプロパティは実際には存在しません。 クラスプロパティは、クラスのインスタンス全体で共有されるプロパティを表しますが、Swiftにおいては、それを直接実現するための仕組みはありません。 代わりに、クラスに対してスタティックプロパティを使用して、クラス全体で共有されるプロパティを表現することができます。

例:

class MyClass {
    static var myProperty: Int = 0
}

print(MyClass.myProperty) // 0
MyClass.myProperty = 10
print(MyClass.myProperty) // 10

let instance1 = MyClass()
let instance2 = MyClass()

print(instance1.myProperty) // 10
print(instance2.myProperty) // 10

この例では、MyClassに対して、myPropertyというスタティックプロパティが宣言されています。インスタンスを生成しなくてもアクセスできるため、クラス全体で共有されるプロパティを表現しています。 このように、スタティックプロパティを使用することで、クラス全体で共有されるプロパティを実現することができます。

ゲッタとセッタについて

ゲッタ

ゲッタは、他のストアドプロパティなどから値を取得して、コンピューテッドプロパティの値として返す処理です。

値の返却には、return文を用います。

次の例では、コンピューテッドプロパティのbodyのゲッタ内で、ストアドプロパティtoを利用した値を取得し、bodyプロパティの値として返しています。

struct Greeting {
    var to = "Sato Takeru"
    var body: String {
        get {
            return "Hello,\(to)"
        }
    }
}

let greeting = Greeting()
greeting.body //"Hello,Sato Takeru"

セッタ

セッタは、プロパティに代入された値を使用して、他のストアドプロパティなどを更新する処理です。

セッタ内では、暗黙的に宣言されたnewValueという定数を通じて代入された値にアクセスできます。この値を使用してセッタの実行時にゲッタがnewValueと同じ値を返せるようにインスタンスを更新します。

次の例は、Temperature型が摂氏温度を表すストアドプロパティcelsiusと華氏温度を表すコンピューテッドプロパティfahrenheitを持っており、ゲッタでは摂氏温度celsiusを華氏温度に変換して値を返し、セッタでは華氏温度newValueを摂氏温度に変換してcelsiusプロパティに代入しています。

struct Temperature {
    // 摂氏温度
    var celsius: Double = 0.0
    // 華氏温度
    var fahrenheit: Double {
        get {
            return (9.0 / 5.0) * celsius + 32.0
        }
        set {
            celsius = (5.0 / 9.0) * (newValue - 32.0)
        }
    }
}

var temperature = Temperature()
temperature.celsius // 0
temperature.fahrenheit // 32

temperature.celsius = 20
temperature.celsius // 20
temperature.fahrenheit // 68

temperature.fahrenheit = 32
temperature.celsius // 0
temperature.fahrenheit // 32

上記の例では、celsiusプロパティとfahrenheitプロパティのどちらか一方を更新すれば、もう一方が同じ温度を表すように更新されます。プロパティ同士に整合性を持たせたい場合に有用です。

まとめ

ここまでSwiftのプロパティについて解説してきました。

皆さんの理解に少しでも役立てたら嬉しいです。

他にもSwiftの記事を書いてるのでよかったら読んでみてください。

また、1人での勉強に限界を感じたらiOSに特化したプログラミングスクール「iOSアカデミア」も検討してみてください!無料相談可能「最短・最速」でiOSエンジニアになれるように手助けしてくれます。