이 프로퍼티 래퍼들은 모두 SwiftUI에게 와 를 알려줍니다. 핵심 구분은 (, )와 (, , ), 그리고 객체의 수명을 누가 책임지는가입니다.
@State@Binding@StateObject@ObservedObject@EnvironmentObject// 이 뷰가 소유하는 값 상태
struct Toggle: View {
@State private var isOn = false // 로컬 단일 진실 공급원
var body: some View {
Switch(isOn: $isOn) // $는 Binding을 생성
}
}
// 다른 곳이 소유한 상태에 대한 양방향 참조
struct Switch: View {
@Binding var isOn: Bool // 소유권 없음; 부모의 상태를 읽고 씀
var body: some View { Button("\(isOn)") { isOn.toggle() } }
}
final class CartModel: ObservableObject {
@Published var items: [Item] = [] // 변경 => 뷰 재렌더링
}
struct CartScreen: View {
@StateObject private var model = CartModel() // 소유: 한 번 생성, 재렌더링에도 유지
var body: some View { CartList(model: model) }
}
struct CartList: View {
@ObservedObject var model: CartModel // 관찰; 부모가 소유
var body: some View { Text("\(model.items.count)") }
}
| 래퍼 | 타입 | 소유권 | 사용 시점 |
|---|---|---|---|
@State | 값 | 이 뷰 | 단순한 로컬 상태 |
@Binding | 값 | 부모 | 자식이 부모의 상태를 편집 |
@StateObject | 참조 | 이 뷰 (한 번 생성) | 뷰가 모델을 생성 |
@ObservedObject | 참조 | 다른 곳 | 모델이 주입됨 |
@EnvironmentObject | 참조 | 상위 뷰 | 트리 깊숙이 공유 |
@StateObject vs @ObservedObject는 고전적인 함정입니다. @ObservedObject var m = Model()로 모델을 생성하면 재렌더링마다 재인스턴스화되어 상태가 조용히 사라집니다. 뷰가 객체를 생성하는 곳에서는 @StateObject를 사용하세요.@EnvironmentObject는 상위 뷰가 .environmentObject(...)로 주입하지 않으면 런타임에 크래시가 납니다.잘못된 래퍼 선택은 SwiftUI 상태 버그의 첫 번째 원인입니다. 값이 깜빡이거나, 스크롤 시 리셋되거나, 뷰가 절대 업데이트되지 않는 문제 말입니다. 면접관이 이를 묻는 이유는 @StateObject vs @ObservedObject 답변이 지원자가 SwiftUI의 소유권 모델을 이해하는지를 즉시 드러내기 때문입니다.
주니어부터 시니어까지 상세한 답변이 포함된 IT 면접 질문 라이브러리.
후원하기