* 해당 글은 개인 공부자료이므로 오류가 있을 수 있습니다.
Swift에서는 struct, class, enum 세 가지 타입을 제공합니다.
이 타입들의 공통점과 차이점을 알아보고 언제 사용해야하는지 알아보겠습니다.
struct PersonStruct {
var name: String
var age: Int
// init() 생략 가능
// 프로퍼티 값 변경 불가능하지만 mutating 사용하여 변경 가능
mutating func increaseAge() {
age += 1
}
}
PersonStruct이름의 구조체를 선언하였습니다.
메모리에는 어떻게 할당되는지 알아보겠습니다.

선언되는 PersonStruct는 위와 같이 데이터 영역에 저장되게 됩니다. 아직 선언만 된 상태 이기 때문에 스택영역에 할당되지 않았습니다. 이제 저장된 데이터를 인스턴스화 시켜 스택영역 메모리에 할당해보겠습니다.
var personStruct1 = PersonStruct(name:"henry", age: 20)
var personStruct2 = personStruct1
personStruct1 이름의 변수에 PersonStruct를 생성해 주고 personStruct1을 personStruct2에 복사를 했습니다. 메모리에서는 아래와 같이 할당되게 됩니다.

personStruct1과 personStruct2는 각각 별개로 스택영역에 인스턴스가 생성됩니다. 값참조 이기 때문에 복사를 하게되면 서로 영향을 주지 않는 별개의 값이 스택영역에 저장되게 됩니다.
personStruct1.increaseAge() // age 1증가
8
print(PersonStruct1.age) // 21
print(PersonStruct2.age) // 20
personStruct1의 age를 증가시키면 스택영역의 personStruct1의 age가 증가되고, personStruct2의 age는 변화가 없습니다.
다음은 참조타입에 대해 알아보겠습니다.
class PersonClass {
var name: String
var age: Int
// init()직접 구현해야됨
init(name:String, age: Int) {
self.name = name
self.age = age
}
// 프로퍼티 값 변경 가능
func increaseAge() {
age += 1
}
}
위 코드와 같이 PersonClass이름을 가진 클래스를 선언했습니다. name과 age의 프로퍼티를 가지고 increateAge()라는 age를 1씩 증가시키는 함수를 가지고 있습니다.
이렇게 선언을 하게 되면 메모리에는 무슨일이 일어날까요?

앞서 값 타입은 스택영역에, 참조타입은 힙영역에 저장된다고했습니다. 하지만 현재는 선언만 한 상태라 클래스는 힙과 스택영역에 존재하지 않고 데이터영역에 PersonClass라는 클래스 데이터가 저장되어있습니다. 이제 이 클래스를 생성해보면 다음과 같습니다.
var personClass1 = PersonClass(name: "henry", age: 20)
var personClass2 = personClass1
personClass1.increaseAge() // age 1 증가
print(personClass1.age) //21
print(personClass2.age) //21
먼저 personClass1이름의 변수에 PersonClass를 생성하고, personClass2에 personClass1복사를 했습니다. personClass1의 age를 1 증가 시켰는데 personClass2의 age 도 1이 증가된 것을 볼 수있습니다. 그 이유는 클래스가 참조타입이기 때문입니다. 이게 어떻게 된건지 메모리 구조를 통해 알아보겠습니다.

PersonClass는 참조타입 클래스이기 때문에 생성을하면, 힙영역에 실제 인스턴스 데이터를 저장하게되고, 스택영역의 personClass1은 힙영역의 데이터를 가르키는 주소값을 갖게됩니다. 따라서 personClass2도 같은 메모리 주소를 가르키는 값을 할당받게 된거죠.
포인트는 "참조타입은 실제 값이 아닌 값을 가르키는 주소값" 입니다.
구조체(struct)
클래스(class)