Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
Tags
- UITextView
- 리펙터링
- Human interface guide
- 리펙토링
- ios
- 애니메이션
- uitableview
- clean architecture
- uiscrollview
- 리팩토링
- Clean Code
- Protocol
- collectionview
- tableView
- combine
- ribs
- SWIFT
- UICollectionView
- Refactoring
- swift documentation
- MVVM
- Xcode
- HIG
- Observable
- RxCocoa
- rxswift
- 스위프트
- 클린 코드
- swiftUI
- map
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - SwiftUI] @State를 사용하면 mutating 없이도 수정이 가능한 원리 (@State 직접 구현해보기) 본문
iOS 응용 (SwiftUI)
[iOS - SwiftUI] @State를 사용하면 mutating 없이도 수정이 가능한 원리 (@State 직접 구현해보기)
jake-kim 2024. 7. 19. 01:32@State를 사용하면 mutating 없이도 사용이 가능
- 아래처럼 @State를 프로퍼티에 붙여서 사용하면 change()함수에서 mutating 키워드가 없더라도 문제없이 동작
struct MyStruct {
@State
var val = 0
func change() {
val = 0
}
}
- struct이기 때문에 값을 변경하려면 원래 mutating키워드가 필요하지만 @State를 사용하면 mutating 없이 사용이 가능
struct MyStruct {
var a1 = 0
func change() {
a1 = 2 // Cannot assign to property: 'self' is immutable
}
}
- computed property, 일반적인 property wrapper모두 mutating이 필요함
struct MyStruct {
@DefaultValue(wrappedValue: 0, defaultValue: 18)
var age: Int
var a1 = 0
var a2: Int {
get { a1 }
set { a1 = newValue }
}
func change() {
age = 1 // Cannot assign to property: 'self' is immutable
a1 = 2 // Cannot assign to property: 'self' is immutable
a2 = 3 // Cannot assign to property: 'self' is immutable
}
}
@propertyWrapper
struct DefaultValue<T> {
private var value: T
private let defaultValue: T
init(wrappedValue: T, defaultValue: T) {
self.value = wrappedValue
self.defaultValue = defaultValue
}
var wrappedValue: T {
get { return value }
set { value = newValue }
}
var projectedValue: T {
get { return defaultValue }
}
}
@State를 사용하면 mutating이 없어도 되는 이유
- @State는 property wrapper인데, property wrapper 내부에서 관리하는 value를 reference type으로 설정하면 가능
- SwiftUI의 @State처럼 만들면 아래처럼 property wrapper 의 value가 class타입으로 정의
private class StateStorage<Value>: ObservableObject {
@Published var value: Value
init(initialValue: Value) {
self.value = initialValue
}
}
@propertyWrapper
struct SimpleState<Value>: DynamicProperty {
@ObservedObject private var stateStorage: StateStorage<Value>
init(wrappedValue: Value) {
self.stateStorage = StateStorage(initialValue: wrappedValue)
}
var wrappedValue: Value {
get { stateStorage.value }
nonmutating set { stateStorage.value = newValue }
}
var projectedValue: Binding<Value> {
Binding(
get: { self.wrappedValue },
set: { self.wrappedValue = $0 }
)
}
}
- 직접 만든 @SimpleState를 사용하면 mutating이 없어도 에러 없이 사용가능
struct MyStruct {
@SimpleState
var a3 = 0
func change() {
a3 = 4
}
}
'iOS 응용 (SwiftUI)' 카테고리의 다른 글
Comments