Value Type
- Struct, Enum, String, etc.
- Stack 메모리에 저장됨
- 빠름
- Tread Safe
- 인스턴스를 할당할 때 참조가 아닌 새로운 데이터를 만들어낸다
Reference Type
- Class, Function, Actor
- Heap 메모리에 저장됨
- 더 느리지만 동기화됐다
- Not Tread Safe
- 인스턴스를 할당할 때 참조할 수 있는 타입으로 제공
Stack
- Value Type 저장
- 각각의 스레드마다 고유의 Stack이 존재
Heap
- Reference Type 을 저장
- Thread 들끼리 공유됩니다.
Struct
- Values 에 기반
- 수정될 수 있음
- Stack 메모리에 저장됨
Class
- References 에 기반 (인스턴스)
- Heap에 저장됨
- 클래스끼리 상속가능
Actor
- 클래스와 같지만 thread safe
사용되는 상황들
Struct: Data Models, Views
Classes: View Mdoels
Actors: Shared 'Manager' and 'Data Store'
View가 Struct으로 사용되는 이유는 Struct이 Class보다 매우 빠르기 때문에 사용되는 것이고
@StateObject
@StateObject로 하나의 클래스 인스턴스를 참조하여 하나의 뷰에서는 하나의 클래스만 이용하여 랜더링하는 것이다.
참조하니까 뷰가 계속 랜더링되어도 매번 다시 만들어지는 것이 아닌 값도 보존이 가능하다.
초기화: @StateObject로 선언된 상태 객체는 뷰가 생성될 때 한 번만 초기화됩니다. 이는 뷰가 다시 그려지더라도 상태 객체가 새로 생성되지 않고 기존의 객체가 재사용된다는 것을 의미합니다. (클래스이고 Reference Type이기 때문에)
메모리 관리: SwiftUI가 상태 객체의 생명 주기를 관리합니다. 뷰가 제거되면 상태 객체도 자동으로 해제됩니다. (ARC에 의해서)
뷰 업데이트: 상태 객체의 프로퍼티값이 변경되면, 해당 객체를 사용하는 뷰가 자동으로 다시 그려집니다(다시 그려져도 뷰는 Struct이기 때문에 매우 빠르기 때문에 여러번 다시 그려져도 상관없음). 이는 ObservableObject 프로토콜과 @Published 속성을 통해 이루어집니다.
즉 클래스의 값이 바껴도 Reference Type으로 참조하면 되기 때문에 하나의 인스턴스로 Heap 메모리에 있는 하나의 클래스에 접근하며 그것을 Struct이기 때문에 여러번 랜더링에 뷰리한 뷰에서 @StateObject를 사용하여 값을 참조할 수 있는 것이다
UIKit은 ViewController는 클래스이기 때문에 SwiftUI에서의 View에 비해 성능이 떨어질 수 밖에 없다.
class StructClassActorViewModel: ObservableObject {
@Published var title: String = ""
init() {
print("ViewModel INIT")
}
}
struct StructClassActor: View {
@StateObject private var viewModel = StructClassActorViewModel()
let isActive: Bool
init(isActive: Bool) {
self.isActive = isActive
print("View INIT")
}
var body: some View {
Text("Hello World!")
.frame(maxWidth: .infinity, maxHeight: .infinity)
.ignoresSafeArea()
.background()
.background(isActive ? Color.red : Color.blue)
}
}
'SwiftUI' 카테고리의 다른 글
Global Actor과 Main Actor (0) | 2024.05.24 |
---|---|
Actor (0) | 2024.05.21 |
Class, ARC, Weak Self (0) | 2024.05.20 |
Struct 구조체 (0) | 2024.05.18 |
Subscripts (0) | 2024.05.17 |