ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Essential Skills for iOS Developers
    카테고리 없음 2024. 3. 1. 18:08

     

    struct와 class의 주요 차이점은 무엇인가요?

    두 차이점을 알아보려고한다. Class는 참조타입이고 ARC로 메모리 관리를 하게되고 struct는 값타입이다가 둘의 가장 대표적인 차이라고 생각을 한다. 이 질문으로 ARC를 통한 메모리 관리, 참조타입과 값타입의 차이점과 엮어서 면접을 준비한다면 도움이 될것이라고 생각한다.

     

    자 일단 차이점을 알아보기위해서 Class 와 Struct 의 공통점을 알아보려고 한다.

     값을 저장할 프로퍼티를 선언할 수 있고 , 함수적기능을 하는 메서드를 선언할 수 있고 . 연산자를 사용해서 접근할 수 있고 extension을 통한 기능을 확장할 수 있고, Protocol 을 채택하여 기능을 설정할 수 있다는 다양한 공통점이 있다 
    그럼이제 공식적인 차이점도 알아보겠다.

    클래스는 참조 타입이고 , ARC로 메모리를 관리합니다. 같은 클래스의 인스턴스를 여러개의 변수에 할당을 한후에 값을 변경시키면 모든 변수에 영향을 끼치기는 하는데 메모리만 복사를 하는개념으로 일어나고 다른언어의 class 와같게 상속이나 타입캐스팅 deinit 를 활용한 메모리 할당 해제 등 많은 것들을 할 수 있지만 struct 는 불가능한것들로 차이점을 생각 할 수 있다. struct 는 딱히 특별한 특징은 없지만 하나는 짚고 넘어가기 위해 여러개의 변수에 할당 한 뒤 값을 변화시키더라도 값을 복사하는개념으로 이벤트가 진행된다.
    조금 더 깊게 들어가보자면 Class와 ARC , Retain Cycle 등 메모리 관리에 대한 이야기를 간단하게 하자면 deinit 를 활용하기위해서는 엮여있는 모든 값들을 모두 해제를 해줘야 deinit 이 실행이 되는데 이러한 원리로 Retain Cycle 가 일어나는것이다. 인스턴스에 접근할 방법이 없는데도 deinit 이 실행되지않는경우 메모리 누수가 발생 하는것이다. 방지하는 방법으로는 weak 참조를 활용하는등의 방법이 있다고 정도만 알고 다음 포스팅에서 자세히 알아보겠다. 
    이제 조금더 심화로 들어가게 되면 메모리에 저장되는 위치가 서로 다르다는 특징도 생기게 된다. 구조체는 언제 생기고 사라지는지를 컴파일 단계에서 알 수 있기 때문에 메모리의 stack 공간에 할당이 되게되고 클래스는 참조가 어디서 어떻게 되는지를 모르기 때문에 heap이라는 공간에 할당이 되는것이다. 

     

     

    Stack 할당

    Stack은 LIFO(Last In First Out) 형태의 자료구조로 가장 마지막에 들어간 객체가 가장 먼저 나오게 되는 자료구조인데요, 자료구조 특성상 하나의 명령어로 메모리를 할당, 해제할 수 있습니다. 또한 컴파일 단계에서 언제 생성되고 해제되는지 알 수 있는 구조체와 같은 값들이 스택에 저장되게 됩니다.

     

    스레드들은 각각 독립적인 Stack 공간을 가지고 있기 때문에 상호 배제를 위한 자원이 필요하지 않습니다. 즉 스레드로부터 안전하다는 말이 됩니다. 이러한 특징 때문에 Stack의 값을 사용하는 것이 Heap의 값을 사용하는 것보다 빠르다고 할 수 있습니다.

    Heap 할당

    Heap에는 컴파일 단계에서 생성과 해제를 알 수 없는 참조 타입의 객체가 할당됩니다. 즉 Swift에서는 클래스 객체가 힙에 할당되게 됩니다. Heap은 Stack보다 관리하기가 어려운데요, 이는 메모리 할당과 해제가 하나의 명령어로 처리되지 않기 때문입니다. 아까 Stack에서는 pop, push라는 하나의 명령어로 할당, 해제가 이루어졌지만 Heap은 참조 계산도 해줘야 하므로 Stack보다 복잡합니다.

     

    또한 Heap은 스레드가 공유하는 메모리 공간이기 때문에 스레드로부터 안전하지 않습니다. 즉 이를 관리해주기 위한 lock과 같은 자원도 필요하게 되고 이는 곧 오버 헤드로 이어지게 됩니다.

     

    이렇게 Stack, Heap 할당의 차이점과 Swift의 Class, Struct 값들이 어디에 저장되는지 알았습니다.

     

    근데 코딩을 하다 보면 클래스와 구조체를 혼합해서 쓰는 경우가 있지 않나요? 예를 들어 클래스 안에 구조체 필드가 있다거나, 구조체 안에 클래스 필드가 있다거나... 하는 경우가 있습니다.

     

    이를 나누게 되면 결국 2가지 경우로 나눌 수 있습니다.

    • 값 타입을 포함하는 참조 타입
      • 간단하게 Class 안에 Struct 프로퍼티가 존재하는 경우입니다.
      • 이 경우 참조 타입이 할당 해제되기 전에 값 타입도 할당 해제되지 않게 하기 위해서 값 타입도 힙에 저장합니다.
      • 위의 경우 말고도 Swift에서는 클로저 내부에서 사용하는 값 타입도 위의 경우에 해당합니다.
    • 참조 타입을 포함하는 값 타입
      • Struct 안에 Class 프로퍼티가 존재하는 경우입니다.
      • 이 경우 값 타입은 힙에 할당되지 않지만 내부에 참조 타입이 있기 때문에 참조 카운트를 처리해줘야 합니다.

    출처: https://icksw.tistory.com/256 [PinguiOS:티스토리] 에서 너무 잘 설명해주셔서 붙여왔다.

     

    이정도로 질문에 대한 답을 정리 하도록 하겠다. ! 

Designed by Tistory.