iOS
웹개발자의 iOS 개발기(2) - struct(구조체), class, @State, @ObservableObject
whh__
2025. 1. 19. 13:35
struct(구조체), class, @State, @ObservableObject에 대하여 공부해 보았습니다.
01. 구조체 - 하나의 동작을 하는 객체 만들기
import SwiftUI
struct Elevator: View {
//@State var level: Int = 1
// 구조체 사용
@State var myElevator = ElevatorStruct()
var body: some View {
VStack {
//Text("층수 : \\(level)")
Text("층수 : \\(myElevator.level)")
HStack{
Button {
// 함수 선언 시 입력받을 파라미터 앞에 _를 붙이면 함수 사용시 파라미터명을 입력하지 않아도 됨
//level = goDown(level)
myElevator.goDown();
} label: {
Text("아래로")
}
Button {
//level = goUp(level: level)
myElevator.goUp();
} label: {
Text("위로")
}
}
}
}
// 입력받을 파라미터 앞에 _ 붙임
func goDown(_ level: Int) -> Int {
return level - 1
}
func goUp(level: Int) -> Int {
return level + 1
}
}
// 구조체 선언
struct ElevatorStruct {
// 층 수를 표시해주는 디스플레이
// 위로 올라갈 수 있어야 함
// 아래로 내려갈 수 있어야 함
var level: Int = 1
mutating func goDown() {
level = level - 1
}
mutating func goUp() {
level = level + 1
}
}
#Preview {
Elevator()
}
mutating
클래스는 참조타입이기 때문에 프로퍼티 변경이 자유로운 반면,
구조체는 값타입이므로 기본적으로 메서드 내에서 인스턴스 프로퍼티를 변경할 수 없다.
메서드에서 값을 변경할 수 있도록 사용하는 키워드가 mutating 이다.
02. 클래스 - 주소값으로 객체를 만들기
import SwiftUI
struct _2_Class_Diff_: View {
var myCar = Car(name: "아반떼", owner: "조우현") // 구조체 사용
@ObservedObject var myKar = Kar(name: "소나타", owner: "조우현2")// 클래스 사용
var body: some View {
VStack {
/*
struce(구조체)로 생성하면 callByValue
*/
Text("struct로 생성")
Text("\\(myCar.name)의 주인은 \\(myCar.owner)입니다")
Button {
myCar.sayHi()
} label: {
Text("출발")
}
Button {
var broCar = myCar
broCar.name = "물려받은 차"
broCar.owner = "동생"
myCar.sayHi() // callByValue
} label: {
Text("물려주기")
}
/*
class로 생성하면 callByValue
*/
Text("class로 생성")
Text("\\(myKar.name)의 주인은 \\(myKar.owner)입니다")
Button {
myKar.sayHi()
} label: {
Text("출발")
}
Button {
let broCar = myKar
broCar.name = "물려받은 차"
broCar.owner = "동생"
myKar.sayHi() // callByReference
} label: {
Text("물려주기")
}
}
}
}
// 구조체 선언
struct Car {
var name: String
var owner: String
func sayHi() {
print("hi \\(owner)")
}
}
// 클래스 선언
class Kar: ObservableObject {
@Published var name: String
var owner: String
init(name: String, owner: String) {
self.name = name
self.owner = owner
}
func sayHi() {
print("hi \\(owner)")
}
}
#Preview {
_2_Class_Diff_()
}
- 구조체 (struct): 값 타입 → Call by Value
- 클래스 (class): 참조 타입 → Call by Reference
03. ObservableObject
@State
- 변경감지 할 변수 선언 시 사용
- View 자체가 구조체(Struct)여서 View 생성 시 멤버변수들이 자동으로 초기화된다. → 그래서 화면을 통해 변수들의 데이터를 수정해도, 화면 재로딩 시 변수의 변경사항을 기억하지 않는다. 이를 방지하기 위해 @State를 변수에 사용해 주면 해당 변수는 다른 스토리지에 저장해 두었다가 불러온다.
위의 @State와 비슷한 용도로 사용된다.
@ObservableObject
- 변경감지 클래스 선언 시 사용
- struct(구조체)에 사용하지 못함
@Published
- 변경감지 클래스의 감지 대상 멤버에 사용
- 데이터가 바뀌면 화면 재로딩