오늘은 저만 모르는 것 같은 Class와 Struct에 대해 알아보려고 합니다.
여러 블로그를 봤지만 무슨 소리인지 모르겠는 말이 너무 많아서, 다른 용어 검색했다가 꼬리에 꼬리를 물고 모르는 것 검색 무한 반복을 하고 있더라고요. 그러다가 다른 길로 새서 결국 원래 찾아보고자 했던 건 잊어버리는..😅
그래서 한꺼번에 정리를 해보려고 해요.
포스팅이 상당히 길어질 것이라는 말ㅎ
이것만 읽고 Class와 Struct를 이해했다! 가 목표
Reference Type (참조 타입)
같은 클래스 인스턴스를 만들고 값을 변경하면 모든 변수에 영향을준다.
class Person {
var name: String = "gosim"
}
// 클래스 / 구조체 / 열거형에서 생성된 객체
// 이게 인스턴스
var instance = Person()
타입 캐스팅 (Type casting) 은 인스턴스의 타입을 확인하거나 해당 인스턴스를 자체 클래스 계층 구조의 다른 곳에서 다른 상위 클래스 또는 하위 클래스로써 취급하는 방법
- 참고: 타입 캐스팅
deinit 메서드가 호출된다. class Person{
var name = "kim"
var age = "20"
deinit {
print("Person 클래스 인스턴스가 소멸됩니다.")
}
}
let kim = Person()
kim = nil // >>> Person 클래스 인스턴스가 소멸됩니다.
객체지향 프로그래밍(Object-Oriented Programming, OOP)은 프로그램을 명령어의 집합으로 보는 것을 넘어, 여러 객체들의 모임으로 보는 것이다.
- 참고 : 객체지향 프로그래밍
Value Type
여러 인스턴스를 만들고 값을 변경해도 , 각 인스턴스의 값은 다르다.
deinit은 클래스의 인스턴스에서만 호출된다. deinit은 사용 불가능하다.함수형 프로그래밍(Functional Programming, FP)이란 "순수함수"를 이용해서 프로그래밍을 하는 것
.를 사용하여 접근할 수 있다.init)를 사용해 초기 상태를 설정할 수 있다.프로토콜 (protocol) 은 메서드, 프로퍼티, 그리고 특정 작업이나 기능의 부분이 적합한 다른 요구사항의 청사진을 정의합니다.
확장 (Extensions) 은 기존의 클래스, 구조체, 열거형, 또는 프로토콜 타입에 새로운 기능을 추가합니다.
class SimpleClass {
var count: Int = 0
deinit {
print("할당 해제")
}
}
struct SimpleStruct {
var count: Int = 0
}
var class1 = SimpleClass()
var class2 = class1
var class3 = class1
class3.count = 3
print(class1.count) // 3
// class3의 값을 변경했지만 참조타입이므로 class1도 변경 되는 것을 볼 수 있습니다.
var struct1 = SimpleStruct()
var struct2 = struct1
var struct3 = struct1
struct2.count = 2
struct3.count = 3
print(struct1.count) // 0
print(struct2.count) // 2 <- 구조체는 값 타입이므로 항상 새로운 메모리가 할당됩니다.
print(struct3.count) // 3
구조체는 언제 생기고, 사라질지 컴파일 단계에서 알 수 있기 때문에 메모리의
Stack 공간에 할당되고
클래스는 참조가 어디서 어떻게 될지 모르기 때문에 Heap이라는 공간에 할당
일단 참조타입은 스택에 저장되긴 하는데, 값이 저장되는 것이 아니라 주소가 저장.
값은 힙에 저장
즉, 참조타입은 힙 영역에 값을 저장하고 이를 가리키는 주소를 스택 영역에 저장

스레드(thread)는 어떠한 프로그램 내에서, 특히 프로세스 내에서 실행되는 흐름의 단위를 말한다. 일반적으로 한 프로그램은 하나의 스레드를 가지고 있지만, 프로그램 환경에 따라 둘 이상의 스레드를 동시에 실행할 수 있다. 이러한 실행 방식을 멀티스레드(multithread)라고 한다.
오버헤드(overhead)는 어떤 처리를 하기 위해 들어가는 간접적인 처리 시간 · 메모리 등을 말한다.
이번에 말하는 오버헤드는 실제 실행되는 메서드를 코드를 훑으며 찾는 과정이다.
즉, 오버헤드가 발생하면 비용이 발생한다.
1. 값 타입을 포함하는 참조타입
2. 참조 타입을 포함하는 값 타입
값 타입의 Copy-on-assignment, Copy-on-write
값 타입을 다른 변수에 할당하면 복사를 하게 됩니다. 즉 새로운 메모리 공간에 같은 값을 복사하게 되는데요, 이를Copy-on-assignment라고 합니다.이와 다르게
Copy-on-write는 다른 변수에 할당하면 일단은 메모리를 할당하지 않고 같은 곳을 봅니다. 그러다 해당 값을 변경할 때 실제로 메모리에 값을 복사하고 값을 변경하게 됩니다. 이는 메모리를 최적화해주기 위함이며 Swift에서는 Int, Double, String, Array, Set, Dictionary에서만 사용하고 있습니다.참조 타입을 포함하고 있는 값 타입은 이러한 메모리 최적화를 할 수 없습니다. 물론 억지로 만들 순 있지만 이는 많은 오버헤드를 발생시킵니다.
https://infinitt.tistory.com/392
https://hasensprung.tistory.com/181
https://velog.io/@scutiuy/Swift-성능-최적화