프로그래밍공부(Programming Study)/IOS 개발

SwiftUI에서 View를 `var`, `struct`, `class`로 선언하는 올바른 방법

Chann._.y 2024. 11. 11.
728x90

1. var로 선언한 View

SwiftUI에서 var를 이용해 View를 선언할 수 있습니다. 이 경우, 주로 structclass 안에서 계산 속성(computed property)으로 View를 정의할 때 사용됩니다.

struct ContentView: View {
    var body: some View {
        Text("Hello, SwiftUI!")
    }
}

특징

  • 계산 속성으로 View를 생성하므로 매번 새로운 View를 반환합니다.
  • 간단한 UI 요소를 반환하는 경우에 적합합니다.

2. struct로 선언한 View

SwiftUI에서 View는 주로 구조체(struct)로 정의됩니다. SwiftUI의 모든 기본 UI 컴포넌트는 구조체로 이루어져 있으며, 이러한 구조체는 값 타입(value type)이기 때문에 인스턴스의 변경이 성능에 큰 영향을 주지 않습니다.

struct CustomTextView: View {
    var text: String

    var body: some View {
        Text(text)
    }
}

특징

  • 구조체는 값 타입으로, 참조가 아닌 복사를 통해 전달됩니다.
  • 불변성이 기본값이기 때문에, 구조체로 선언된 View는 데이터 상태의 변경에 따라 새로운 인스턴스가 생성됩니다.
  • SwiftUI에서 UI를 만들 때 가장 흔히 사용하는 방식입니다.

장점

  • 메모리 관리가 효율적이며, SwiftUI의 상태 기반 업데이트 모델과 잘 맞습니다.
  • 간결한 코드 작성이 가능하고, UI 요소의 성능 최적화에 유리합니다.

3. class로 선언한 View

SwiftUI는 구조체 중심이지만, 특정 상황에서는 클래스(class)를 이용해 View를 정의할 수 있습니다. 클래스는 참조 타입(reference type)이기 때문에, 상태를 변경하여 참조된 모든 곳에서 영향을 주어야 하는 경우에 유용합니다.

class CounterViewModel: ObservableObject {
    @Published var count = 0
}

struct CounterView: View {
    @ObservedObject var viewModel: CounterViewModel

    var body: some View {
        VStack {
            Text("Count: \(viewModel.count)")
            Button("Increment") {
                viewModel.count += 1
            }
        }
    }
}

특징

  • 클래스는 참조 타입이므로, 특정 상태를 공유할 때 유용합니다.
  • SwiftUI에서는 상태 관리용 ObservableObject 프로토콜과 함께 사용하여 View에 상태 변화를 전달할 수 있습니다.
  • 여러 View에서 동일한 인스턴스의 데이터를 참조하여 업데이트를 반영할 수 있습니다.

장점

  • 데이터 공유가 필요한 경우 매우 유용하며, 동일한 객체를 여러 View에서 참조할 수 있습니다.
  • 상태 변화를 객체 참조를 통해 쉽게 추적할 수 있습니다.

4. 각 선언 방식의 장단점 비교

선언 방식 사용 목적 장점 단점
var 계산 속성 단순한 View 반환 구현이 간단함 매번 새로운 View 생성
struct 기본 View 구조 값 타입으로 효율적인 메모리 관리 데이터 변경에 따른 새로운 인스턴스 필요
class 상태 관리 참조 타입으로 여러 곳에서 공유 가능 메모리 관리가 어려워질 수 있음

5. 언제 어떤 방식을 선택할지에 대한 가이드라인

  • 단순한 UI 요소를 반환할 때는 var로 선언해 계산 속성으로 구현합니다.
  • 기본적인 SwiftUI의 View 컴포넌트는 대부분 구조체(struct)로 선언하여 성능을 최적화하고, 값 타입을 활용합니다.
  • 상태를 공유하거나 동기화할 필요가 있는 경우에는 class를 사용하여 ObservableObject와 함께 활용합니다.

6. 실습 예제 코드

아래는 classstruct를 함께 사용하는 예제입니다. CounterViewModel 클래스를 통해 상태를 관리하고, 구조체로 View를 구성합니다.

import SwiftUI

// ObservableObject 클래스로 상태 관리
class CounterViewModel: ObservableObject {
    @Published var count = 0
}

struct CounterView: View {
    // View에서 상태를 관찰
    @ObservedObject var viewModel: CounterViewModel

    var body: some View {
        VStack {
            Text("Count: \(viewModel.count)")
                .font(.largeTitle)
                .padding()
            Button("Increment") {
                viewModel.count += 1
            }
            .padding()
        }
    }
}

struct ContentView: View {
    // CounterViewModel 인스턴스를 생성하여 전달
    @StateObject private var viewModel = CounterViewModel()

    var body: some View {
        CounterView(viewModel: viewModel)
    }
}

이 예제에서 CounterViewModel@Published 속성을 사용하여 상태 변화를 감지하고, CounterView는 이를 참조하여 UI를 업데이트합니다.

728x90

댓글