반응형
Property Wrapper란?
Swift의 Property Wrapper는 프로퍼티에 특정 기능을 추가할 수 있도록 도와주는 기능입니다. 반복적으로 사용되는 로직을 추상화하여 코드의 중복을 줄이고, 가독성을 높이는 데 기여합니다. 예를 들어, UserDefaults에 값을 저장하거나, 특정 프로퍼티에 대한 유효성 검사를 수행할 때 Property Wrapper를 활용할 수 있습니다.
Property Wrapper를 사용하는 이유와 장점
Property Wrapper를 사용하면 다음과 같은 이점이 있습니다.
- 코드 재사용성 증가: 동일한 로직을 여러 프로퍼티에 적용할 때 중복 감소
- 가독성 향상: 프로퍼티가 어떻게 동작하는지 명확하게 나타낼 수 있음
- 캡슐화: 내부 구현을 감추고, 프로퍼티가 더 명확한 역할을 수행할 수 있도록 함
- SwiftUI와의 연계: SwiftUI에서는 @State, @Binding, @ObservedObject 등의 Property Wrapper를 통해 상태 관리가 용이
주요 Property Wrapper와 차이점
Swift에서 제공하는 대표적인 Property Wrapper 몇 가지를 살펴보겠습니다.
@State
- 정의: SwiftUI에서 사용되는 Property Wrapper로, View 내부에서 상태를 저장할 때 사용됩니다.
- 특징:
- View가 상태를 직접 소유하고 관리함.
- 상태가 변경되면 View가 다시 렌더링됨.
- 구조체(struct)에서만 사용 가능.
- 사용 예시
import SwiftUI
struct CounterView: View {
@State private var count = 0
var body: some View {
VStack {
Text("\(count)")
Button("증가") {
count += 1
}
}
}
}
@Binding
- 정의: @State와 함께 사용되며, 부모 View의 상태를 자식 View에서 수정할 수 있도록 해줍니다.
- 특징:
- @State 변수의 참조를 전달하여, 부모의 상태를 직접 변경할 수 있음.
- 부모 View의 상태가 변경되면 자식 View도 변경됨.
- 사용 예시:
struct ParentView: View {
@State private var count = 0
var body: some View {
CounterButton(count: $count)
}
}
struct CounterButton: View {
@Binding var count: Int
var body: some View {
Button("증가") {
count += 1
}
}
}
@ObservedObject
- 정의: ObservableObject 프로토콜을 따르는 클래스를 참조하여 View에서 데이터 변경을 감지할 수 있도록 합니다.
- 특징:
- 클래스 기반(class)으로 상태를 저장함.
- @Published 속성을 사용하여 변경 사항을 알림.
- View가 @ObservedObject를 참조하고 있을 경우, 해당 객체의 상태가 변경되면 View가 다시 렌더링됨.
- 사용 예시
class Counter: ObservableObject {
@Published var count = 0
}
struct CounterView: View {
@ObservedObject var counter = Counter()
var body: some View {
VStack {
Text("\(counter.count)")
Button("증가") {
counter.count += 1
}
}
}
}
@EnvironmentObject
- 정의: View 계층 구조에서 공유되는 객체를 참조할 때 사용됩니다.
- 특징:
- @ObservedObject와 유사하지만, 더 상위 계층의 View에서 주입 가능.
- environmentObject(_:)를 사용하여 부모 View에서 객체를 설정해야 함.
- 사용 예시
class Counter: ObservableObject {
@Published var count = 0
}
struct CounterView: View {
@EnvironmentObject var counter: Counter
var body: some View {
VStack {
Text("\(counter.count)")
Button("증가") {
counter.count += 1
}
}
}
}
Custom Property Wrapper 만들기
Swift에서는 직접 Property Wrapper를 정의하여 사용할 수도 있습니다. 예를 들어, 특정 값의 최소 및 최대 범위를 제한하는 Property Wrapper를 만들어 보겠습니다.
예제: 범위 제한 Property Wrapper
@propertyWrapper
struct Clamped<Value: Comparable> {
private var value: Value
private let range: ClosedRange<Value>
init(wrappedValue: Value, _ range: ClosedRange<Value>) {
self.range = range
self.value = range.contains(wrappedValue) ? wrappedValue : range.lowerBound
}
var wrappedValue: Value {
get { value }
set { value = range.contains(newValue) ? newValue : (newValue < range.lowerBound ? range.lowerBound : range.upperBound) }
}
}
사용 예시
struct Player {
@Clamped(0...100) var health: Int = 50
}
var player = Player()
player.health = 120 // 자동으로 100으로 조정됨
player.health = -10 // 자동으로 0으로 조정됨
마무리
Swift의 Property Wrapper는 상태 관리 및 데이터 처리 로직을 캡슐화하여 코드의 가독성을 높이고 유지보수를 용이하게 만듭니다. 기본적으로 제공되는 @State, @Binding, @ObservedObject 등의 Wrapper를 활용하면 SwiftUI에서 더욱 효율적인 상태 관리를 할 수 있습니다. 또한, 필요에 따라 Custom Property Wrapper를 정의하여 다양한 상황에 맞춰 활용할 수도 있습니다.
반응형
'프로그래밍언어' 카테고리의 다른 글
[Swift] ABI(Application Binary Interface) 안정성 (0) | 2025.02.19 |
---|---|
[Swift] 동적 멤버 조회(Dynamic Member Lookup) (0) | 2025.02.19 |
[Swift] UnsafePointer, UnsafeMutablePointer, UnsafeRawPointer 차이점과 사용법 (0) | 2025.02.19 |
[JAVA] Checked Exception에 대하여 (0) | 2025.02.17 |
[Swift] COW (Copy-On-Write) (0) | 2025.02.16 |