본문 바로가기

프로그래밍/SWIFT

[SwiftUI] @State, struct, class

반응형

https://www.hackingwithswift.com/books/ios-swiftui/why-state-only-works-with-structs

why state only works with structs 라는 제목의 강의.

swiftui 에서 변경될 수 있는 변수에 @State 를 붙이는 것에 익숙해졌다. 이 @State 변수에는 스위프트의 기본 형 뿐만 아니라, 사용자형도 사용할 수 있다. 다음과 같다.

struct User {
    var firstName = "Bilbo"
    var lastName = "Baggins"
}

struct ContentView: View {
    @State private var user = User()
    
    var body: some View {
        VStack {
            VStack {
                Text("Your name is \(user.firstName) \(user.lastName).")
                
                TextField("First name", text:$user.firstName)
                TextField("Last name", text:$user.lastName)
            }
        }
        .padding()
        .frame(minWidth: 200, minHeight: 200)
    }
}

아주아주 간단한 swiftui 화면이다. 사용자의 이름과 성을 입력/변경할 수 있는 TextField 를 두 개 만들었고, 사용자명 전체를 표시하는 Text 뷰가 하나 있다. 이름이나 성이 변경되면, swiftui 는 이 변경을 감지해서, Text 뷰 안의 이름까지 잘 바꿔준다.

하지만, struct 로 정의한 User 를 class 로 바꾸어버리면, 이 동작이 잘 되지 않는다. TextField 의 이름을 바꾸어도 위 Text 뷰안의 이름이 바뀌지 않고 최초의 이름을 유지한다.

이 차이에 대해 Paul Hudson 의 설명은 이러하다.

struct 일 때에는, User struct 의 프로퍼티가 변경되면, 실제로는 새로운 struct 인스턴스가 만들어진다. 그래서 @State 가 변경을 알아차리고, 자동으로 view 를 리로드하게 된다.

class 일 때에는 (클래스 인스턴스는 그대로인채로) 값이 직접 변경된다. 그래서 @State 가 변경을 알아채지 못하고, view 의 리로드도 일어나지 않는다.

struct 는 mutating 키워드가 있을 때에만, 내부 프로퍼티가 변경이 가능했다. 그래서 struct 의 프로퍼티 변경은 struct 자체가 새롭게 만들어지면서 이루어진다. 하지만, class 는 원래 mutating 키워드가 필요 없이, 내부 프로퍼티의 변경이 가능하다.

728x90