>100 Views
March 21, 20
スライド概要
2020/03/21 に swift zoomin' で発表した資料です。プロパティーアクセスしたときに追加処理を行う仕組みの Property Wrappers を、類似機能に感じる didSet と、同じく似たようなことが実現できうる独自型について、特徴を比較しながら Property Wrappers とはどういったものなのかを眺めていきます。
※ Docswell での公開に移行する直前の Slideshare での閲覧数は 783 でした。
正統派趣味人プログラマー。プログラミングとは幼馴染です。
Property Wrappers ͷಛΛோΊΔ ۽୩༑ !FT@LVNBHBJ 4XJGU;PPNJO`
ϓϩύςΟʔೖ࣌ͷՃॲཧ willSet / didSet & Property Wrappers 4XJGU
֓ཁ 1SPQFSUZ8SBQQFSTͷجຊ͔Β
֓ཁ 1SPQFSUZ8SBQQFST ϓϩύςΟʔͷಡΈॻ͖࣌ʹɺՃॲཧΛ࣮ߦ͢ΔΈ Ͱܕఆٛͯ͠ɺଐੑͱͯ͠ϓϩύςΟʔʹׂΓͯΔ ྨࣅػೳʁ ⾣ willSetdidSet
֓ཁ 8SBQQFSͷఆٛ ⾣ ܕΛ@propertyWrapperଐੑΛఴ͑ͯఆٛ ⾣ wrappedValueϓϩύςΟʔΛհͯ͠ՃॲཧΛ࣮ @propertyWrapper struct PassThrough<Value> { var wrappedValue: Value init(wrappedValue value: Value) { wrappedValue = value } }
֓ཁ 8SBQQFSͷద༻ ⾣ ϓϩύςΟʔΛ@型名ଐੑΛఴ͑ͯఆٛ ⾣ ϓϩύςΟʔͷܕwrappedValueͷܕΛࢦఆ struct Data { @PassThrough var value: Int }
֓ཁ ߏΠϝʔδ อଘॴͱͯ͠XSBQQFE7BMVF͕༻ҙ͞ΕΔ XSBQQFE7BMVF1SPQFSUZ8SBQQFSܕΛհͯ͠ಡΈॻ͖͢Δ Object @XXX var value: YYY @propertyWrapper XXX init(wrappedValue:) એݴ var wrappedValue ࢀর ॳظԽ
ػೳൺֱ ྨࣅͦ͠͏ͳػೳͱͷൺֱ
ػೳൺֱ ࣮ྫΛߟ͑Δ ʲ͓ʳཁૉΛྻͯ֨͠ೲ͢Δม 1SPQFSUZ8SBQQFSͰͷ࣮ྫ EJE4FUͰͷ࣮ྫ ಠࣗͰܕͷ࣮ྫ
ػೳൺֱ 8SBQQFSͰͷ࣮ྫ @propertyWrapper struct Sorting<Element : Comparable> { private var elements: [Element] init(wrappedValue: [Element]) { elements = wrappedValue } var wrappedValue: [Element] { get { elements } set { elements = newValue.sorted() } } } @Sorting var values: [Int] = []
ػೳൺֱ EJE4FUͰͷ࣮ྫ var values: [Int] = [] { didSet { values = values.sorted() } }
ػೳൺֱ ಠࣗͰܕͷ࣮ྫ struct OrderedArray<Element : Comparable> { private(set) var elements: [Element] public init() { elements = [] } mutating func append(_ element: Element) { elements = (elements + [element]).sorted() } } var values: OrderedArray<Int>
ػೳൺֱ ͦΕͧΕͷಛ 1SPQFSUZ8SBQQFST EJE4FU ࣮ͰܕΛఆٛ ܕͷείʔϓͰॲཧΛ࣮ ॴଐઌͷʹܕӨڹΛ༩͑ͳ͍ ࣮ΛEJE4FUͰఆٛ ॴଐઌͷείʔϓͰॲཧ Өڹൣғͷ੍͕ޚඞཁ ϓϩύςΟʔͱಠཱ࣮ͨ͠ ϓϩύςΟʔຖʹຒΊࠐΈ δΣωϦΫεʹΑΔ൚༻Խ͕Մೳ ֤ϓϩύςΟʔʹಛԽ࣮ͨ͠ Ͱܕͷఆٛͱద༻͕ඞཁ खܰͳଈ੮࣮ ಡΈॻ͖ͷ྆ํͰՃॲཧ͕Մೳ ॻ͖ࠐΈ࣌ͷΈՃॲཧ͕Մೳ
ػೳൺֱ ͦΕͧΕͷಛ 1SPQFSUZ8SBQQFST ಠࣗܕ ࣮ͰܕΛఆٛ ͜ͷείʔϓͰॲཧΛ࣮ ॴଐઌͷʹܕӨڹΛ༩͑ͳ͍ ࣮ͰܕΛఆٛ ͜ͷείʔϓͰॲཧΛ࣮ ॴଐઌͷʹܕӨڹΛ༩͑ͳ͍ ϓϩύςΟʔͱಠཱ࣮ͨ͠ ϓϩύςΟʔͱಠཱ࣮ͨ͠ δΣωϦΫεʹΑΔ൚༻Խ͕Մೳ δΣωϦΫεʹΑΔ൚༻Խ͕Մೳ ଐੑͰϓϩύςΟʔͷੑ࣭Λදݱ ͰܕϓϩύςΟʔͷੑ࣭Λදݱ
ػೳൺֱ ੑ֨తͳಛ 1SPQFSUZ8SBQQFST EJE4FU ⾣ Ͱܕఆٛ͢Δߏ ⾣ ίʔυϒϩοΫͰఆٛ͢Δߏ ⾣ ϓϩύςΟʔʹߴͳॲཧΛ༩ ⾣ ೖޙͷՃॲཧͱ࣮ͯ͠ ⾣ ଐੑΛͬͯؔ࿈͚Δ ಠࣗܕ ⾣ Ͱܕఆٛ͢Δߏ ⾣ σʔλදػͯ͠ͱݱೳΛ࣮
͍͚ͷߟ ͦͷͨΊͷ֤ํ๏ͷಛൺֱ ίʔυͷ࠶ར༻͕૪ʁ ಛघॲཧͷಁ໌ੑʁ ΦϒδΣΫτࢦͱͷ૬ੑʁ
͍͚ͷߟ ίʔυͷ࠶ར༻͕૪ʁ 1SPQFSUZ8SBQQFST EJE4FU ⾣ ಉ͡ՃॲཧͳΒ࠶ར༻͕Մೳ ⾣ ϓϩύςΟʔຖʹಛԽ࣮ͨ͠ ⾣ δΣωϦΫεʹΑΔ൚༻Խ͕Մೳ ⾣ ࠶ར༻ʹ֎෦͕ؔඞཁ ಠࣗܕ ⾣ ಉ͡ৼΔ͍ͳΒ࠶ར༻͕Մೳ ⾣ δΣωϦΫεʹΑΔ൚༻Խ͕Մೳ
͍͚ͷߟ ಛघॲཧͷಁ໌ੑʁ 1SPQFSUZ8SBQQFST EJE4FU ⾣ ଐੑʹΑΓ૾Մೳ ⾣ ࣮Λͱ͍ͳݟผͰ͖ͳ͍ ⾣ ͨͩ͠ଐੑϔομʔʹදΕͳ͍ ⾣ ࣮ϔομʔʹදΕͳ͍ ⾣ ࣮Λͱ͍ͳݟผͰ͖ͳ͍ ಠࣗܕ ⾣ ʹܕΑΓ૾Մೳ ⾣ ܕใͱͯ͠ϔομʔʹݱΕΔ ⾣ ίʔυิʹݱΕΔ
͍͚ͷߟ ΦϒδΣΫτࢦͱͷ૬ੑʁ 1SPQFSUZ8SBQQFST ⾣ ܕࢉܭϓϩύςΟʔͰ ΦʔόʔϥΠυՄೳ ⾣ ΦʔόʔϥΠυͨ͠ઌͰ ଐੑΛ৽ͨʹࢦఆͰ͖ͳ͍ ಠࣗܕ ⾣ ܕࢉܭϓϩύςΟʔͰ ΦʔόʔϥΠυՄೳ EJE4FU ⾣ ܕࢉܭϓϩύςΟʔͰ ΦʔόʔϥΠυՄೳ
͍͚ͷཁॴ ֤ํ๏Λ͍͚ΔஅࡐྉͱͳΓಘΔࣄฑ
1SPQFSUZ8SBQQFST ⾣ طଘͷʹܕɺ൚༻తͳՃੑ࣭Λ༩ ⾣ ϓϩύςΟʔʹద༻Ͱ͖ΔϓϩτίϧΈ͍ͨͳଘࡏ ⾣ ಡΈॻ͖ͷ྆ํʹରԠ ʹܕಛੑΛ༩ > ϓϩτίϧΈ͍ͨͳҹ EJE4FU ⾣ ؆୯ɾ໌ྎʹՃॲཧΛ࣮Ͱ͖Δػೳ ⾣ ॴଐઌͷείʔϓͰಈ࡞ɺີʹ࿈͢ܞΔͷ͕༰қ ⾣ ॻ͖ࠐΈ࣌ͷΈରԠ ՃॲཧΛ࣮ > defer Έ͍ͨͳҹ ಠࣗܕ ⾣ σʔλߏͱͯ͠ੑ࣭Λ࣮ ⾣ Ճॲཧͱͯ͠Ͱͳ͘ɺͦͷͷͷੑ֨Λنఆ σʔλܕΛఆٛ
ಛ༗ͷػೳ 1SPQFSUZ8SBQQFSͳΒͰͷػೳΛѲ
ಛ༗ͷػೳ 4ZOUIFTJ[FE4UPSBHF1SPQFSUZ ⾣ _Λ໊͚ͨલͰࣗಈఆٛ ⾣ QSJWBUFͳ1SPQFSUZ8SBQQFSܕͷ A Type ⾣ Λӡ༻͢ΔͨΊͷػೳΛ 1SPQFSUZ8SBQQFS͕ܕఏڙՄೳ ⾣ QSJWBUFΞΫηεϨϕϧͰ ॴଐઌͷଆͰ͚ͩར༻Մೳ @Sorting var values: [Int] private var _values: Sorting<Int>
ಛ༗ͷػೳ
1SPQFSUZ8SBQQFSʹܕϝιουΛࡌ
⾣
4ZOUIFTJ[FE4UPSBHF1SPQFSUZʹҙͷϝιουΛࡌՄೳ
⾣
FYUFOTJPOΛͬͯͷࡌՄೳ
@propertyWrapper
extension Sorting {
func ascending -> [Element] {
A Type
@Sorting var values: [Int]
elements.sorted(by: <)
}
}
func XXXX() {
_values.sorted(by: .ascending)
ಛ༗ͷػೳ
ҾʹΑΔॳظԽ
⾣
ΠχγϟϥΠβʔͰXSBQQFE7BMVFҎ߱ʹҾΛՃ
⾣
༻࣌ʹύϥϝʔλʔΛࢦఆՄೳʹ
@propertyWrapper
struct Sorting<Element> {
init(wrappedValue: [Element], order: Order) {
}
A Type
@Sorting(order: .descending) var values: [Int] = []
ಛ༗ͷػೳ طఆΠχγϟϥΠβʔ ⾣ Ҿͳ͠ͷΠχγϟϥΠβʔΛఆٛͯ͠طఆΛఆٛ ⾣ ॳظΛهड़͠ͳ͍ॳظԽΛఏڙՄೳ @propertyWrapper struct Sorting<Element> { A Type @Sorting var values: [Int] init() { elements = [] } ⾣ એظॳͰ͚ͩݴԽ࣮ߦ ⾣ ॴଐઌͷΠχγϟϥΠβʔͰ ॳظԽ͢Δ߹Ͱ࣮ߦ͞ΕΔ
ಛ༗ͷػೳ 1SPKFDUJPO7BMVF ⾣ QSPKFDUFE7BMVFΛఆ͓ٛͯ͘͠ͱ$Λ໊͚ͨલͰར༻Մೳʹ ⾣ ࿈͢ܞΔҙͷΛఏڙՄೳ @propertyWrapper struct Sorting<Element> { var projectedValue: SomeType { A Type @Sorting var values: [Int] } private var $values: SomeType
&OKPZ4XJGU 5IBOLZPV ۽୩༑ !FT@LVNBHBJ