ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Class vs Struct in Swift
    Swift 2019. 10. 21. 17:01

    공통점

    • properties와 methods를 정의할 수 있다.
    • subscript를 정의할 수 있다. (subscript syntax를 사용할 수 있다.)
    • init 함수를 통해 초기화 할 수 있다.
    • extension을 사용할 수 있다.
    • protocol로 적합하다.

    차이점

    • class는 다른 class를 상속받을 수 있다.
    • class는 deinitialized 할 수 있다.
    • class는 reference type이고 struct는 value type이다.

     

    특히 마지막 차이점이 중요한데, 이 차이가 우리가 둘 중 무엇을 사용할 지 결정적이기 때문이다.

    class와 struct의 가장 큰 차이는 struct는 value type, class는 reference type이라는 것이다.

    value type은 복사할 때 새로운 data를 복사해서 같은 data가 2개 생기고

    reference type은 복사할 때 data의 주소를 복사해서 한 data의 reference가 2개 생긴다.

     

    Struct가 더 좋은 경우

    class를 써야할 이유가 없다면 기본적으로 struct를 쓰는 것이 권장된다.

    • 단순 데이터 타입이라면 struct를 사용하자.
      단순한 newItem, user, task 등의 object들을 전달하고 싶은 경우를 생각해보자. object 자체로 잘 정의되어 있어서 따로 이들이 갖는 object 사이의 관계는 전달할 필요가 없다면 struct가 적합하다.
    • 멀티 쓰레드 환경이라면 struct가 더 안전하다.
      struct는 race condition, deadlock 등의 위험없이 다른 쓰레드로 복사되지만 class는 thread-safe하게 숙고해서 사용해야 한다.
    • Struct의 properties는 String 등의 기본 타입과 마찬가지로 value 타입이다.
      따라서 class가 아닌 struct를 사용하는게 합리적이다. class type에서 struct를 사용하는 건 괜찮지만 value type에서 class를 사용하려면 매우 주의해야 한다. class는 reference type이기 때문에 만약 struct의 reference가 class instance를 공유했다는 사실을 모른다면 문제가 생긴다.

    Struct를 사용하면 코드를 이해하기 유리하다. Struct 타입이라면 코드의 다른 부분에서 struct의 reference를 유지하고 있지 않음을 확실히 할 수 있다. 명시적으로 바꾸지 않는다면 코드의 다른 부분에 의해 변하지 않는다.

     

    Class가 더 좋은 경우

    class의 특징이 필요할 때 class를 사용하는 것이 좋다. 먼저 class의 특징을 살펴보자

    • class는 다른 class를 상속받을 수 있다.
      class MyViewController: UIViewController 와 같이 subclass를 만들어 사용할 수 있다. struct는 protocols을 만들어 사용해야 한다.
    • class는 deinitialize할 수 있다.
      deinit 함수를 만들어 사용할 수 있다. 또 같은 class의 reference를 여러개 만들 수 있다.
    • class에는 identity가 내재되어 있다. === 연산자를 사용해 두 reference를 비교할 수 있다.

    또 중요한 특징은 Swift와 Objective-C를 함께 쓰고 싶다면 class를 사용해야 한다. realm을 사용할 때 처럼@objcdynamic 등을 사용하고 싶다면 class여야 한다.

    다음으로 reference type과 value type의 차이를 보자. 상속은 class와 struct의 매우 중요한 차이다. class는 상속을 통해 부모와 자식간의 관계를 명확히 할 수 있다.

    예를들어 이런식이다.

    • MyViewController는 ViewControll를 상속받는다.
    • MyTableViewController는 InfiniteTableViewController를 상속받는데, 이는 Infinite scrolling을 갖는 UITableViewController의 자식이다.
    • Car와 Bike는 Vehicle을 상속받는데, 이는 둘다 vehicle의 특징을 갖고있기 때문이다.

    마지막 두 가지에는 위험이 도사리고 있다.

    한번에 상속관계를 명확히 하면 좋겠지만, 길을 잃기 쉽다. SuperCar가 Vehicle에서 필요 없는 기능을 상속받는다면? SuperBike와 SuperCar는 비슷한 기능을 가졌지만 서로 다른 상속을 받았기 때문에 이 기능을 공유할 수 없다면? 이러한 경우에는 Protocol-Oriented Programming이 적합할 것이다.

    이를 바탕으로 다음과 같은 상황에 class를 사용하는 것이 적합하다고 볼 수 있다.

    • 복사하거나 비교되지 않는 경우.
      Window나 ViewController는 딱 한 번만 실행되고 사용된다.
    • 인스턴스의 lifecylce이 외부에 달려있을 때.
      DB나 임시파일 등은 disk에서 복사본을 만드는 건 적합하지 않다. 같은 data를 참조하는 것이 적합하다.
    • 단순히 외부 상태를 나타내기 위할 때.
      API나 online resource를 돕거나 참조하기 위한 class가 필요할 수 있다. 이들은 단순히 정보를 전달하기 위한 통로지 이를 복사하면 안된다.

    **요약하면, 상속, identity, Objective-c를 사용할 때, 값이 복사되면 안되는 상황에서 class를 사용하면 좋다.**

    참고

    Struct vs. Class In Swift Explained - LearnAppMaking

    'Swift' 카테고리의 다른 글

    inout  (0) 2019.10.24
    Variadic functions, 불특정 개수 파라미터  (0) 2019.10.24
    KVO(Key-Value-Observing)  (0) 2019.09.20
    Swift) 배열의 중복체크  (0) 2019.07.25
    Swift) 소수점 다루기  (0) 2019.07.22

    댓글

Designed by Tistory.