TIL(Today I Learned)

Value type VS Reference type

Swift 문법 기초 강의를 듣다보니 class와 struct의 차이를 배우게 되었습니다.
이전까지 코틀린으로 개발을 할때는 struct를 사용해본적이 없었습니다. (아마 아예 존재하지 않는 키워드 같은데 확실히 모르겠음..)
그나마 사용하는 경우를 생각해보면 data class와 비슷한 것 같기도한데 도무지 정리가 잘되지 않았습니다.
그래서 이곳 저곳을 찾아보던 중 class와 struct의 차이를 머리에 집어 넣기 전에 Value type과 Reference type의 차이를 먼저 공부하고 넘어가야 할 것 같다는 생각이 들었습니다.

Value type은 ‘복사’ / Reference type은 ‘바로가기’
  • Value type을 다른 변수에 할당하면 인스턴스가 복사됩니다.
  • Reference type을 다른 변수에 할당하면 인스터스 자체가 아닌 그 인스턴스의 주소값을 복사합니다
Value type은 불변성이 있습니다.
  • Value type은 매번 복사되기 때문에 원래 인스턴스의 데이터가 바뀌지 않습니다.
  • Reference type은 할당하면 여러 식별자가 같은 주소값을 가리키기 때문에 다른 부분에서도 데이터를 변경할 수 있습니다. -> Side effect 발생 가능성
‘Struct’ = Value type / ‘Class’ = Reference type
  • Struct와 Enum 키워드로 생성한 모든 type은 Value type입니다.
  • Class 키워드로 생성한 모든 type은 Reference type입니다.
Swift에 이미 존재하는 타입은 기본적으로 Value type
  • Swift Standard library와 Foundation에 존재하는 거의 대부분 타입은 모두 Value type입니다.
    • Int, Double, Bool, String 등은 Struct로 구현되어있습니다.
  • function, closure는 데이터를 복사하지않고 참조를 공유하기 때문에 Reference type입니다.
Collection은 Value type 이자 Reference type
  • Swift 컴파일러는 Copy-on-write 라는 방법을 사용
    • Collection에서 변경이 발생할때만 새로운 값을 복사
    • Reference type의 효율성
    • Value type의 불변성
메모리 - Text, Data, Stack, Heep
  1. Text 영역 - 앱이 실행해야 할 프로그램의 코드를 저장
  2. Data 영역 - 프로그램의 전역 변수, 정적 변수를 저장, 어디서든 접근 가능하며 프로세스가 끝날때까지 유지
  3. Stack 영역 - 지역변수나 파라미터 같은 일시적인 데이터를 저장, 함수를 호출할 때마다 Stack에 함수 공간 할당
  4. Heap 영역 - 데이터를 지우기 전까지는 계속 유지, 반영구적 지속
Value type은 Stack 영역에 Reference type은 Heap 영역에
  • Value type의 인스턴스는 Stack에 저장
    • 시스템은 현재 실행하는 스레드와 관련된 컨텍스트를 Stack에 저장
    • Stack 영역은 CPU가 직접 관리, 최적화 -> 빠르고 효울적
  • Reference type의 인스턴스는 Heap에 저장
    • 인스턴스 자체는 Heap영역에 저장하고 주소값을 식별자와 함께 Stack에 저장
    • Heap 영역에 있는 인스턴스는 직접 지워줘야하고 빈 메모리를 적절하게 삽입해줘야 할 필요가 생깁니다. -> Stack에 비해 속도가 느리고 비효율적
Value type이 Heap 영역에 Reference type이 Stack 영역에 (예외)
  • Value type -> Heap
    • Array, Dictionary, Set, String 등은 Value type이지만 최적화를 위해서 Heap 영역을 같이 활용
  • Reference type -> Stack
    • 전체 사이즈에 제한이 있고, 변수의 크기를 자유롭게 바꿀 수 없다는 Stack의 특징 -> Reference type 중에도 크기가 고정되어 있거나, 컴파일러가 삭제 타이밍을 예측할 수 있는 경우에는 Stack을 사용해서 성능을 향상 시킵니다.
Class 보다는 Struct
  • struct가 class보다 빠르고 안전하다는 장점이 있으므로 struct를 우선으로 고려
  • Class를 사용하는 경우
    1. 고유성이 필요한 인스터스일 경우 - 값이 같다고 두 인스턴스가 같다고 할 수 없는 이유는 레퍼런스 타입의 인스턴스가 ‘고유성’을 가지기 때문입니다.
    2. Objective-C와의 호환성이 필요한 경우
    3. 변경 가능한 상태를 공유하는 것이 꼭 필요한 경우 - Linked list를 구현할 때 처럼 데이터의 상태를 계속해서 업데이트해야할 때
상속이 필요한 경우에는 Class?
  • struct는 상속이 불가능 -> 상속이 필요한 경우에는 class 사용
  • struct + protocol로 class의 상속을 대체 가능하며 오히려 더 권장

댓글남기기