[Swift] PropertyWrapper 手を動かして理解する(その3 $ もしくは projectedValue の理解)

     
⌛️ 2 min.

Property wrapper の基本的なところを見てきたので、@State の理解に欠かせない $ の意味を説明します。

Swift [Swift] PropertyWrapper 手を動かして理解する(その1 wrappedValue)

Swift [Swift] PropertyWrapper 手を動かして理解する(その2 wrappedValue の初期化)

property wrapper 復習

WrapIntLowerLimit


@propertyWrapper struct WrapIntLowerLimit {
  private var value: Int = 0
  private var lowerLimit:Int = 0
  init(wrappedValue:Int) {
    self.value = wrappedValue
  }
  init(wrappedValue: Int, lowerLimit:Int) {
    self.value = wrappedValue
    self.lowerLimit = lowerLimit
  }
  var wrappedValue: Int {
    get {
      return value
    }
    set {
      self.value = max(newValue, lowerLimit)
    }
  }
}

class CheckWrapInt {
  @WrapIntLowerLimit var value:Int = 0
}

var varInt = CheckWrapInt()
print(varInt.value)          // (1) varInt.value.wrapperValue へのアクセスになる

property wrapper “WrapIntLowerLimit” を指定した CheckWrapInt クラスのインスタンス varInt 中の プロパティ value にアクセスすると、
value.wrappedValue へのアクセスになっていました。

これが、property wrapper の基本的な意味でした。

$ の意味

プロパティ名に $ をつけてアクセスすると、それは、projectedValue へのアクセスになります。”それだけ”です。

プロパティ名が、value であれば、$value は、value.projectedValue にアクセスすることを意味します。

この projectedValue をどのように実装するかは、property wrapper の自由です。

projectedValue については、特にタイプの制約もありません。本当に自由です。

$ を付けて使用することがなければ、projectedValue を定義しなくても良いです。

それだけだとそっけないので、すこし実例を紹介します。

projectedValue を使って設定できるようにする

property wrapper の初期化を使って、WrapIntLowerLimit の下限を設定することもできましたが、projectedValue を使って設定できるようにしてみます。

WrapIntLowerLimit with projectedValue


@propertyWrapper struct WrapIntLowerLimit {
  private var value: Int = 0
  private var lowerLimit:Int = 0
  init(wrappedValue:Int) {
    self.value = wrappedValue
  }
  init(wrappedValue: Int, lowerLimit:Int) {
    self.value = wrappedValue
    self.lowerLimit = lowerLimit
  }
  var wrappedValue: Int {
    get {
      return value
    }
    set {
      self.value = max(newValue, lowerLimit)
    }
  }
  var projectedValue: Int {          (1)
    get {
      lowerLimit
    }
    set {
      self.lowerLimit = newValue     (2)
    }
  }
}

class CheckWrapInt {
  @WrapIntLowerLimit var value:Int = 0
}

var cwi = CheckWrapInt()
print(cwi.value)              // 
cwi.value = -4                // (3)  cwi.value.wrappedValue へのアクセス
print(cwi.value)              // (4)
cwi.$value = -5               // (5)  cwi.value.projectedValue へのアクセス
cwi.value = -4                // (6)  cwi.value.wrappedValue へのアクセス
print(cwi.value)              // (7)

(1),(2) のように、projectedValue へのアクセスを lowerLimit へのアクセスになるように設定します。

(3) で、-4 を設定しようとしても、lowerLimit は、初期値 0 なので、(4) では、0 と表示されます。(これまでと同じ動作です)
(5) で $ 経由で projectedValue を設定しています。これは、lowerLimit を設定することになるので、(5) は、lowerLimit に -5 を設定することを意味します。ですので、(6) で設定された -4 は、そのまま (7) でも -4 と表示されます。

まとめ

property wrapper での $ の意味
  • projectedValue へのアクセスを意味する
  • Type は、自由に設定できる

あっけないくらい簡単です。ここまでの 3回の記事を見てもらえれば、 property wrapper は、難しくないことがわかりますし、自分で使うアイデアも思い浮かぶと思います。

ぜひ、property wrapper を活用して下さい。

では、なぜ、@State 等を理解することが難しいのか? それは、@State の projectValue の定義にあります。

次の記事で説明します。

説明は以上です。

不明な点やおかしな点ありましたら、ご連絡いただけるとありがたいです。

SwiftUI ViewMatery

SwiftUI で開発していくときに、ViewやLayoutのための適切なmodifierを探すのが大変です。
英語での説明になってしまいますが、以下の”SwiftUI Views Mastery Bundle”という本がビジュアル的に確認して探せるので、便利です。

英語ではありますが、1ページに コードと画面が並んでいるので、非常にわかりやすいです。

View に適用できる modifier もわかりやすく説明されているので、ビューの理解だけではなく、どのような装飾ができるかも簡単にわかります。

超便利です

SwiftUIViewsMastery

販売元のページは、こちらです。

SwiftUI 徹底入門

# SwiftUI は、毎年大きく改善されていますので、少し古くなってしまいましたが、いまでも 定番本です。

Swift学習におすすめの本

詳解Swift

Swift の学習には、詳解 Swift という書籍が、おすすめです。

著者は、Swift の初期から書籍を出していますし、Swift の前に主力言語だった Objective-C という言語についても同様の書籍を出しています。

最新版を購入するのがおすすめです。

現時点では、上記の Swift 5 に対応した第5版が最新版です。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です