ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 웹개발자의 iOS 개발기(2) - struct(구조체), class, @State, @ObservableObject
    iOS 2025. 1. 19. 13:35

    struct(구조체), class, @State, @ObservableObject에 대하여 공부해 보았습니다.

    01. 구조체 - 하나의 동작을 하는 객체 만들기

    import SwiftUI
    
    struct Elevator: View {
        
        //@State var level: Int = 1
        
        // 구조체 사용
        @State var myElevator = ElevatorStruct()
        
        var body: some View {
            VStack {
                //Text("층수 : \\(level)")
                Text("층수 : \\(myElevator.level)")
                
                HStack{
                    Button {
                        // 함수 선언 시 입력받을 파라미터 앞에 _를 붙이면 함수 사용시 파라미터명을 입력하지 않아도 됨
                        //level = goDown(level)
                        
                        myElevator.goDown();
                    } label: {
                        Text("아래로")
                    }
                    
                    Button {
                        //level = goUp(level: level)
                        
                        myElevator.goUp();
                    } label: {
                        Text("위로")
                    }
    
                }
            }
        }
        
        // 입력받을 파라미터 앞에 _ 붙임
        func goDown(_ level: Int) -> Int {
            return level - 1
        }
        
        func goUp(level: Int) -> Int {
            return level + 1
        }
    }
    
    // 구조체 선언
    struct ElevatorStruct {
        // 층 수를 표시해주는 디스플레이
        // 위로 올라갈 수 있어야 함
        // 아래로 내려갈 수 있어야 함
    
        var level: Int = 1
        
        mutating func goDown() {
            level = level - 1
        }
        
        mutating func goUp() {
            level = level + 1
        }
    }
    
    #Preview {
        Elevator()
    }
    
    

    mutating

    클래스는 참조타입이기 때문에 프로퍼티 변경이 자유로운 반면,

    구조체는 값타입이므로 기본적으로 메서드 내에서 인스턴스 프로퍼티를 변경할 수 없다.

    메서드에서 값을 변경할 수 있도록 사용하는 키워드가 mutating 이다.

    02. 클래스 - 주소값으로 객체를 만들기

    import SwiftUI
    
    struct _2_Class_Diff_: View {
        
        var myCar = Car(name: "아반떼", owner: "조우현")  // 구조체 사용
        @ObservedObject var myKar = Kar(name: "소나타", owner: "조우현2")// 클래스 사용
        
        var body: some View {
            VStack {
                
                /*
                 struce(구조체)로 생성하면 callByValue
                 */
                Text("struct로 생성")
                Text("\\(myCar.name)의 주인은 \\(myCar.owner)입니다")
                
                Button {
                    myCar.sayHi()
                } label: {
                    Text("출발")
                }
                Button {
                    var broCar = myCar
                    broCar.name = "물려받은 차"
                    broCar.owner = "동생"
                    
                    myCar.sayHi()   // callByValue
                } label: {
                    Text("물려주기")
                }
                
                
                /*
                  class로 생성하면 callByValue
                 */
                Text("class로 생성")
                Text("\\(myKar.name)의 주인은 \\(myKar.owner)입니다")
                
                Button {
                    myKar.sayHi()
                } label: {
                    Text("출발")
                }
                Button {
                    let broCar = myKar
                    broCar.name = "물려받은 차"
                    broCar.owner = "동생"
                    
                    myKar.sayHi()   // callByReference
                } label: {
                    Text("물려주기")
                }
    
            }
            
        }
    }
    
    // 구조체 선언
    struct Car {
        var name: String
        var owner: String
        
        func sayHi() {
            print("hi \\(owner)")
        }
    }
    
    // 클래스 선언
    class Kar: ObservableObject {
        @Published var name: String
        var owner: String
        
        init(name: String, owner: String) {
            self.name = name
            self.owner = owner
        }
        
        func sayHi() {
            print("hi \\(owner)")
        }
    }
    
    #Preview {
        _2_Class_Diff_()
    }
    
    
    • 구조체 (struct): 값 타입 → Call by Value
    • 클래스 (class): 참조 타입 → Call by Reference

    03. ObservableObject

    @State

    • 변경감지 할 변수 선언 시 사용
    • View 자체가 구조체(Struct)여서 View 생성 시 멤버변수들이 자동으로 초기화된다. → 그래서 화면을 통해 변수들의 데이터를 수정해도, 화면 재로딩 시 변수의 변경사항을 기억하지 않는다. 이를 방지하기 위해 @State를 변수에 사용해 주면 해당 변수는 다른 스토리지에 저장해 두었다가 불러온다.

    위의 @State와 비슷한 용도로 사용된다.

    @ObservableObject

    • 변경감지 클래스 선언 시 사용
    • struct(구조체)에 사용하지 못함

    @Published

    • 변경감지 클래스의 감지 대상 멤버에 사용
    • 데이터가 바뀌면 화면 재로딩
Designed by Tistory.