[Swift] PropertyWrapper 手を動かして理解する(その1 wrappedValue)
[Swift] PropertyWrapper 手を動かして理解する(その2 wrappedValue の初期化)
Sponsor Link
property wrapper 復習
@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 を使って設定できるようにしてみます。
@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 と表示されます。
まとめ
- projectedValue へのアクセスを意味する
- Type は、自由に設定できる
あっけないくらい簡単です。ここまでの 3回の記事を見てもらえれば、 property wrapper は、難しくないことがわかりますし、自分で使うアイデアも思い浮かぶと思います。
ぜひ、property wrapper を活用して下さい。
では、なぜ、@State 等を理解することが難しいのか? それは、@State の projectValue の定義にあります。
次の記事で説明します。
説明は以上です。
不明な点やおかしな点ありましたら、ご連絡いただけるとありがたいです。
Sponsor Link