Swift中结构和类之间的区别,SwiftUI也没有更新

Posted

技术标签:

【中文标题】Swift中结构和类之间的区别,SwiftUI也没有更新【英文标题】:Difference between struct and class in Swift, also SwiftUI not updating 【发布时间】:2021-10-17 12:28:52 【问题描述】:

我遇到了一些问题并写了一些基本的变体来显示问题:

import SwiftUI

struct PersonStruct 
    // Requires @State because self.name is immutable otherwise
    @State var name:String

    init (_ name: String)  self.name = name 
    
    func changeName(_ name: String) 
        self.name = name
        print (self.name)
    


class PersonClass 
    var name:String

    init (_ name: String)  self.name = name 
    
    func changeName(_ name: String) 
        self.name = name
        print (self.name)
    


struct ContentView: View 
    var person1:PersonStruct = PersonStruct("Peter S.")
    var person2:PersonClass = PersonClass("Peter C.")

    var body: some View 
        VStack 
            Text(person1.name)
            .padding()
            Text(person2.name)
            .padding()
            
            Button("Change name") 
                person1.changeName("Trevor")
                person1.name = "Trevor"

                person2.changeName("Trevor")
                person2.name = "Trevor"

                print("---")
                print (person1.name)
                print (person2.name)
            
            .padding()
        
        .font(.title)
    


struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView()
    

person 变量的行为不同,按下按钮将 person2 的名称从“Peter C”更改为 Trever - 如控制台中的“print”所示。 但是 person1 的名字不会改变,它保持在“Peter S”。 ...

因此,该结构似乎根本不起作用。

在这两种情况下,视图中的文本输出都不会改变 - “Peter C”和“Peter S”保持可见。

为什么 person1 的内容没有改变? 我什至使用了函数“changeName()”,还尝试直接设置名称。 无济于事:-(

【问题讨论】:

您不应在非 SwiftUI 结构中使用 @State,即不符合 View 的结构。另一方面,您应该将@State 用于ContentView 中的两个属性。如果您仍有问题,请修复并返回 删除结构中的@State 给出了“无法分配给属性:'self' 是不可变的”,如上所述。但是 vadian 的“变异”确实解决了这个问题! 【参考方案1】:

首先它要求struct中的name标有@State,其实反正是错的,只要把函数设为mutating就行了

struct PersonStruct 
    var name : String

    init (_ name: String)  self.name = name 
    
    mutating func changeName(_ name: String) 
        self.name = name
        print (self.name)
    

为了能够观察类采用ObservableObject并添加属性包装器@Published

class PersonClass : ObservableObject 
    @Published var name:String

    init (_ name: String)  self.name = name 
    
    func changeName(_ name: String) 
        self.name = name
        print (self.name)
    

在视图中将结构声明为@State,将类声明为@StateObject

@State private var person1 = PersonStruct("Peter S.")
@StateObject private var person2 = PersonClass("Peter C.")

【讨论】:

这就像一个魅力,非常感谢!使用“@State”而不是“@StateObject”似乎也适用于 person2 ... 规则是:@State 用于值类型,@StateObject 用于引用类型。

以上是关于Swift中结构和类之间的区别,SwiftUI也没有更新的主要内容,如果未能解决你的问题,请参考以下文章

Swift 结构体和类的区别

swift语言中的结构与类

Swift-Class和Struct的区别(结构体和类的区别)

c++ 中空类的大小和联合、结构和类之间的区别是啥?

Swift中 Class和Struct的区别

在 2 个页面 SwiftUI 之间传递状态