일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- UserDefaults
- 데드락
- 오브젝트
- scrollview
- decode
- core data
- deadlock
- @state
- 가상 메모리
- IOS
- 100 days of SwiftUI
- 인프런
- 동기화
- async
- Apple Developer Academy
- SwiftUI
- 상호배제
- 알고리즘
- 비동기
- 프로세스 스케줄링
- struct
- COLOR
- forEach
- 앨런
- Algorithm
- 운영체제
- Codable
- 동시성
- Swift
- Linked List
Archives
- Today
- Total
기어가더라도 제대로
[SwiftUI-기초] class 인 인스턴스의 상태 보존(@StateObject, @ObservedObject) 본문
SwiftUI - 기초
[SwiftUI-기초] class 인 인스턴스의 상태 보존(@StateObject, @ObservedObject)
Damagucci-juice 2022. 11. 2. 15:07- 기존에 struct 인 인스턴스는 @State 로 상태 변화를 감지하고 뷰를 업데이트할 수 있었다.
2022.11.01 - [SwiftUI - 기초] - [SwiftUI-기초] @State가 쓸모 없어지는 지점에 대하여(class, struct)
- 지금부터는 클래스를 사용하기 위해서 어떻게 해야하는지 정리해보려한다.
- @EnvironmentObject, @StateObject, @ObservedObject 를 주로 사용하는데, 이중에서 뒤에 두개를 탐구해보려 한다.
class User {
var firstName = "Bilbo"
var lastName = "Baggins"
}
struct ContentView: View {
@State private var user = User()
var body: some View {
VStack {
Text("Your name is \(user.firstName) \(user.lastName).")
TextField("First name", text: $user.firstName)
TextField("Last name", text: $user.lastName)
}
}
}
- 위와 같은 코드를 사용해도, 앱의 구동은 가능하나, view 의 업데이트가 안된다는 것을 알 수 있다.
- 이를 위해 클래스에서 앱이 관심있어할 만한 부분이 업데이트가 되었다는 것을 알려야한다.
- 관심있어할만한 이라는 말이 키워드다
@Published - 뷰가 관심 가질 변수
class User {
@Published var firstName = "Bilbo"
@Published var lastName = "Baggins"
}
- 우리는 User 클래스의 인스턴스에서 성씨 부분과 이름 변수의 변화에 주목하고 싶다.
- 그럴 때 @Publish 키워드를 사용한다.
- 해당 키워드가 달린 변수가 업데이트가 되면 업데이트된 사실을 알리는 키워드이다.
- SwiftUI 뷰는 이 둘중 하나의 프로퍼티만 업데이트 되어도 Body를 다시 그린다.
- 그러나 이것만으론 부족하다. SwiftUI에게 이 객체가 변화하는 것을 보아야한다고 선언을 해주어야한다.
@StateObject - 인스턴스를 주목하세요.
// ContentView
@StateObject var user = User()
- SwiftUI에게 이 인스턴스의 모든 변화는 주목되어야합니다. 즉 이 객체는 주목되어야합니다. 라고 알리는 키워드
- 그런데 이 키워드를 달 수 있는 클래스는 특정 클래스로 한정된다. 어떤 클래스가 가능하냐면..
protocol ObservableObject
class User: ObservableObject {
@Published var firstName = "Bilbo"
@Published var lastName = "Baggins"
}
- 이 프로토콜은 아무런 요구사항도 요구하지 않는다.
- 단지 이것을 채택하는 클래스는 관찰될 수 있다는 것을 알리는 역할을 하는 프로토콜이다.
결론
- class 에 ObservableObject 프로토콜을 채택
- 그 클래스 중에서 관찰이 되어야하는 프로퍼티에 @Published 키워드 달아줌
- SwiftUI가 View에서 해당 인스턴스를 알아볼 수 있도록 @StateObject 키워드 달아줌
완성 코드
class User: ObservableObject {
@Published var firstName = "Bilbo"
@Published var lastName = "Baggins"
}
struct ContentView: View {
@StateObject private var user = User()
var body: some View {
VStack {
Text("Your name is \(user.firstName) \(user.lastName).")
TextField("First name", text: $user.firstName)
TextField("Last name", text: $user.lastName)
}
}
}
번외 1. @ObservedObject VS. @StateObject
- 약간 @State 와 @Binding 의 관계와 비슷하다. (혹은 그것의 class 버전이라 이해해도 좋다.)
- @StateObject: 해당 인스턴스를 그 뷰에서 만드는 경우
- @ObservedObject: 해당 인스턴스를 다른 뷰에서 넘겨받는 경우
- 상황 가정
- A라는 뷰에서 클래스의 인스턴스를 만들었는데 B라는 뷰에서도 같은 인스턴스를 봐야하는 경우에
- A 뷰에서 인스턴스 생성: @StateObject
- B 뷰에서 인스턴스 선언: @ObservedObject
번외 2. @State == @Published + @StateObject
- @State 는 절반은 @Published 이고 나머지 절반은 @StateObject 이다.
- @State의 역할 = 해당 클래스의 프로퍼티 변화 감시 + 해당 인스턴스를 감시해야한다고 뷰에게 알림
- @Published: 해당 클래스의 프로퍼티 변화 감시
- @StateObject: 이 클래스의 인스턴스를 감시해야한다고 뷰에게 알림
참조
https://www.hackingwithswift.com/books/ios-swiftui/sharing-swiftui-state-with-stateobject
'SwiftUI - 기초' 카테고리의 다른 글
[SwiftUI-기초] Custom Color, dark mode (0) | 2022.11.04 |
---|---|
[SwiftUI-기초] .Sheet: modal 로 페이지 넘기기(dismiss) (0) | 2022.11.03 |
[SwiftUI-기초] @State가 쓸모 없어지는 지점에 대하여(class, struct) (0) | 2022.11.01 |
[SwiftUI-기초] custom transition (0) | 2022.10.31 |
[SwiftUI-기초] Animation의 View적인 특성(+ Drag, transition) (0) | 2022.10.30 |
Comments