คือ didSet อยู่บน@ถูกเชื่อมโยงแฟ้มเศรษฐกิจของสหรัฐ

0

คำถาม

โดยพื้นฐานแล้วฉันการซ้อนใน @Binding 3 ชั้นลึกมาก

struct LayerOne: View {
    @State private var doubleValue = 0.0
    
    var body: some View {
        LayerTwo(doubleValue: $doubleValue)
    }
}

struct LayerTwo: View {
    @Binding var doubleValue: Double {
        didSet {
            print(doubleValue)
        }
    }
    
    var body: some View {
        LayerThree(doubleValue: $doubleValue)
    }
}

struct LayerThree: View {
    @Binding var doubleValue: Double {
        didSet {
            print(doubleValue) // Only this print gets run when doubleValue is updated from this struct
        }
    }

    var body: Some view {
        // Button here changes doubleValue
    }
}

แล้วแต่ตาม struct ฉันเปลี่ยน doubleValue ในคืนที่หนึ่งอยู่ที่ไหน didSet จะได้วิ่งหนีดังนั้นสำหรับตัวอย่างเช่นถ้าฉันเปลี่ยนแปลงมันอยู่ LayerThree แค่นั้นใครจะพิมพ์เรื่องของคนอื่นจะทำเอง

ฉันสามารถเฝ้าดูการเปลี่ยนแปลงของกัน .onChange(of: doubleValue) ซึ่งจะให้วิ่งหนีตอนที่มันจะเปลี่ยนแต่มันไม่ใช่การตอบสนกับฉันทำไม didSet ไม่ได้วิ่งยกเว้นที่ struct ยู่ที่ไหนมันเปลี่ยนแปลงจาก.

นี่ @Binding struct เศรษฐกิจของสหรัฐ

swift swiftui
2021-11-22 18:09:26
3

คำตอบที่ดีที่สุด

1

ใช้ทรัพย์สินผู้สังเกตุการณ์แบบ didSet บค่าต่างๆถูกพันอยู่ PropertyWrappers จะไม่มีคำว่า"ปกติ"ลูกเล่นเพราะคืนค่าที่ตั้งไว้ภายใน wrapper.

ใน SwiftUI ถ้าคุณอยากจะกระตุ้นการกระทำเมื่อมีค่าเปลี่ยนแปลงคุณควรใช้ onChange(of:perform:) ตัวแปลง.

struct LayerTwo: View {
    @Binding var doubleValue: Double
    
    var body: some View {
        LayerThree(doubleValue: $doubleValue)
          .onChange(of: doubleValue) { newValue 
            print(newValue)
          }
    }
}
2021-11-22 18:26:49

เสร็จฉันดังนั้นเหมือนฉันคิดว่า...มันเป็นการตั้งค่าจากภายใน struct นั่นมันตั้งไม่ได้ขึ้นอยู่ผ่านเจ๋งสุดยอดแฟลตต่างหาก
Joe Scotto
0

ตอนนี้ทั้งหมดที่ทำงาน:

struct ContentView: View {
    
    var body: some View {
        
        LayerOne()
        
    }
    
}


struct LayerOne: View {
    
    @State private var doubleValue:Double = 0.0 {
        didSet {
            print("LayerOne:", doubleValue)
        }
    }
    
    var body: some View {
        LayerTwo(doubleValue: Binding(get: { return doubleValue }, set: { newValue in doubleValue = newValue } ))
    }
    
}

struct LayerTwo: View  {
    
    @Binding var doubleValue: Double {
        didSet {
            print("LayerTwo:", doubleValue)
        }
    }
    
    var body: some View {
        
        LayerThree(doubleValue: Binding(get: { return doubleValue }, set: { newValue in doubleValue = newValue } ))
    }
}




struct LayerThree: View  {
    
    @Binding var doubleValue: Double {
        didSet {
            print("LayerThree:", doubleValue) 
        }
    }
    
    var body: some View {
        
        Text(String(describing: doubleValue))
            
        Button("update value") {
            doubleValue = Double.random(in: 0.0...100.0)
        }
        .padding()
    }
    
}

พิมพ์ผล:

LayerOne:64.58963263686678

LayerTwo:64.58963263686678

LayerThree:64.58963263686678

2021-11-22 18:20:58

แต่ทำไมคุณต้องการต้องส่งต่อเชื่อมความเลวร้ายแบบนั้นหรือคะ ไม่ควร didSet นลาภอันประเสริฐเชื่อฉันเถโดยไม่คำนึงถึงที่ถูกเชื่อมโยงคือเปลี่ยนไปหรือเปล่า?
Joe Scotto

ฉันคิดว่าพวกเราไม่สามารถถามทำไมหรือยังไงเพราะมันคือแอปเปิ้ลแล้วก็ปิดแหล่งข่าว ที่ทำให้ didSet เริ่มทำงานคุณต้องการ initialization เพื่อผูกมัดหรอ.
swiftPunk
0

เพื่อดูทำไมสิ่งนี้เกิดขึ้นเราสามารถ unveil ที่ syntactic น้ำตาลของทรัพย์สินห่อนี้. @Binding var doubleValue: Double translates ไปยัง:

private var _doubleValue: Binding<Double>
var doubleValue: Double {
    get { _doubleValue.wrappedValue }
    set { _doubleValue.wrappedValue = newValue }
}

init(doubleValue: Binding<Double>) {
    _doubleValue = doubleValue
}

อะไรก็ตามที่คุณทำอยู่ didSet จะเอาหลังจากเส้น _doubleValue.wrappedValue = newValue. มันควรจะมาเห็นได้ชัดว่าทำไมตอนที่คุณปรับปรุง doubleValue ในเลเยอร์ 3 ค didSet ของ doubleValue ในชั้น 2 หรือ 1 ไม่ได้โทรมา พวกเขาเป็นเพียงต่างออกส่วนที่คำนวณแล้วคุณสมบัติ!

swiftPunk เป็นทางออก ทำงานโดยสร้างใหม่ถูกเชื่อมโยงของใคร setter ตั้งค่า struct น doubleValueจึงเรียก didSet:

Binding(get: { return doubleValue }, 
        set: { newValue in doubleValue = newValue }
//                         ^^^^^^^^^^^^^^^^^^^^^^
//                         this will call didSet in the current layer
2021-11-22 18:37:59

ในภาษาอื่นๆ

หน้านี้อยู่ในภาษาอื่นๆ

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................