본문 바로가기

카테고리 없음

[Swift] 클래스(class)와 구조체(struct) 둘 중에 뭐가 더 좋은데 ? 어 !?

시간은 소중하니 바로 알아보도록 하자

 

뭐가더 좋은지를 알아보기전에 간단히 공통점과 클래스, 구조 그들만의 특정을 짚고 넘어가려고 한다.

클래스와 구조체의 공통점

  • 값을 저장하기위한 프로퍼티 정의
  • 기능을 제공하기 위한 메서드 정의
  • subscript문법을 이용해 특정 값을 접근
  • 초기 상태를 설정할 수 있는 initializer정의
  • 기본 구현에서 기능확장
  • 프로포콜 순응(conform)

더 많은 정보는 프로퍼티,메소드,서브스크립트, 초기화, 확장 그리고 프로토콜을 참조하면된다.


구조체만의 특징

  • 프로퍼티에 대한 이니셜라이저가 자동생성된다(굳이 적지않아도됨)
  • 클래스와 달리 상속할 수가 없다.
  • 인스턴스를 let으로 설정하면 프로퍼티 값을 변경할 수 없다.

(ps.- 스위프트의 기본 데이터 타입은 모두)

 

구조체 사용이 적합한 상황이나 예시

????

 

일반적으로 다음의 조건 중 1개 이상을 만족하면 구조체를 사용하는 것을 고려해볼 수 있습니다.

 

  • 구조체의 주 목적이 관계된 간단한 값을 캡슐화 하기 위한 것인 경우 
  • 구조체의 인스턴스가 참조되기 보다 복사되기를 기대하는 경우 ???? 
  • 구조체에 의해 저장된 어떠한 프로퍼티가 참조되기 보다 복사되기를 기대하는 경우 
  • 구조체가 프로퍼티나 메소드 등을 상속할 필요가 없는 경우 

https://jusung.gitbook.io/the-swift-language-guide/language-guide/09-classes-and-structures#pointers

 

클래스과 구조체 (Classes and Structures)

 

jusung.gitbook.io

공식 문서에서 나와있는 대로 인데 솔직히 이렇게 말해주니 어쩌라는건지 혼란만온다.... 실제 코드 구현된거라도 보여주면 모를까 그만한 예시가 애매해서 없는거겠지 ?


클래스만의 특징

  • 구조체와 다르게 이니셜라이저가 수동이다.
  • 인스턴스를 let으로 생성하면 프로퍼티값을 변경할 수 있다.
  • 클래스는 참조가 되어있지않으면 메모리에서 해재가 되고 deinit()메서드 함수가 실행된다.
  • identity가 들어있어서 ===, !== 를통해서 reference를 비교할 수 있다
  • 상속(inheritance) : 클래스의 여러 속성을 다른 클래스에 물려줌
  • 타입 캐스팅(Type Casting) : 런타임 클래스에 인스턴스의 타입을 확인
  • 소멸자(Deinitializers) : 할당된 자원을 해재(free up) 시킴
  • 참조 카운트(Reference counting) : 클래스 인스턴스에 하나 이상의 참조가 가능

 

클래스 사용이 적합한 상황이나 예시

???

 


간단히 차이점과 공통점 정도만 있고 클래스와 구조체의 각각 적합한 예시는 보다시피 ???? 로 마무리가 되어있다.

이유는 공식 Swift문서를 통해서 명쾌한 답을 얻을 수가 없었다. 

그러던 와중에 한글은 원본이아니니 영문으로 구글에 class 와 struct 둘중 어느것을 사용해야하나요 ? 라고 검색을 해봤다

 

http:// 미리보기 15:33 How to use Structs vs Classes in the Swift Programming ... YouTube · Devslopes 2020. 3. 22.

이 형의 영상을 접했고 힌트를 얻을 수 있겠다 싶었다.

근데 이형은 시원하게 말한다

일반적으로 Apple공식문서에서 struct를 사용하라고 말했어요 ~ 왜냐면 메모리 효율이 아주 좋거든요~

ㅇ,ㅇ ?? 그래 ?? 바로 애플문서를 찾아본다

 

["Apple Which class or structure is more efficient in Swift language?"] 라고 검색을 했고

https://developer.apple.com/documentation/swift/choosing_between_structures_and_classes

 

Apple Developer Documentation

 

developer.apple.com

 

공식문서를 읽어보았다.

한번 정리해보자

 

구조와 클래스 도대체 뭘써야하는건데 ?! 어 !?

 

우선 들어가자마자 보이는 내용이 둘다 데이터를 저장하고 동작을 모델링하는데 좋은 선택이지만, 유사성으로 인해 서로를 선택하기 어려울 수 있다라고 말하고 있다 ㅋㅋ ㅇㅈ

 

그래도 시원하게 마음을 헤아려주니 Apple공식문서 신뢰가간다


일단 앱에 새 데이터유형을 추가할 때 적합한 옵션을 선택하는 데 도움이 되도록 다음권장 사항을 고려하십시오.

 

  1. 기본적으로 구조를 사용합니다.
  2. Object-C상호 운용성이 필요할 때 클래스를 사용하십시오.
  3. 모델링하는 데이터의 ID를 제어해야하는 경우 클래스를 사용합니다.
  4. 프로토콜과 함께 구조를 사용하여 구현을 공유하여 동작을 채택합니다(참고로 프로토콜 공부가안된상태 ㅜ)

 

  1. 기본적으로 구조 선택
  • Swift의 구조에는 다른언어의 클래스로 제한되는 많은 기능이 포함되어 있다. 여기에는 저장속성, 계산 속성 및 메서드가 포함 될 수 있으며 게다가 Swift구조는 기본 구현을 통해 동작을 얻기 위해 프로포콜을 채택할 수 있다. Swift표준 라이브러리와 Fountdation은 숫자, 문자열, 배열 및 사전과 같이 자주 사용하는 유형에 대한 구조를 사용합니다.

#구조를 사용하면 좋은점?

  • 기본적으로 구조를 선택

구조를 사용하면 앱의 전체 상태를 고려할 필요 없이 코드의 일부에 대해 더 쉽게 추론할 수 있습니다. 

구조는 클래스와 달리 값 유형이기 때문에 구조에 대한 로컬 변경 사항은 앱 흐름의 일부로 이러한 변경 사항을 의도적으로 전달하지않는 한 앱의 나머지 부분에 표시되지 않습니다.

=> 그러니깐 지역변수를 사용해도 앱의 전체적인 틀에 영향을 끼치지는 않기때문에 안전하다는 의미인갑..

 

결과 적으로 코드 섹션을 볼 수 있고 접선 관련 함수 호출에서 보이지 않게 변경되는 것이 아니라 해당 색션의 인스턴스에 대한 변경이 명시적으로 이루어질 것이라는 확신을 가질 수 있습니다.

 

  • Object-C 상호 운용성이 필요할 때 클래스 사용

데이터를 처리해야 하는 Objective-C API를 사용하거나 데이터 모델을 Objective-C 프레임워크에 정의된 기존 클래스 계층에 맞춰야 하는 경우 클래스 및 클래스 상속을 사용하여 데이터를 모델링 해야 할 수 있습니다. 

예를 들어, 많은 Objective-C 프레임워크는 하위 클래스로 예상되는 클래스를 노출합니다.

 

=> 다른 외부 API의 맞는 모델은 기존 모델계층에 맞춰야하는 경우 에는 클래스 상속을 받아 데이터를 모델링한다.

  • ID를 제어해야 할 때 클래스 사용

Swift의 클래스는 참조 유형이기 때문에 기본 제공 ID 개념이 있습니다. 이는 두 개의 서로 다른 클래스 인스턴스가 각각의 저장된 속성에 대해 동일한 값을 가질 때 ID 연산자( ===)에 의해 여전히 서로 다른 것으로 간주된다는 것을 의미합니다.

 

중요한

신원을 조심스럽게 다루십시오. 앱 전체에 걸쳐 클래스 인스턴스를 널리 공유하면 논리 오류가 발생할 가능성이 높아집니다. 많이 공유되는 인스턴스를 변경하는 결과를 예상하지 못할 수도 있으므로 이러한 코드를 올바르게 작성하는 것이 더 중요합니다.

 

  • 정체성을 통제하지 못할 때 구조를 사용하라 ( 이해하기 어렵다 ) 

 

외부에서 가져오는 모델과 비슷한 걸 다룰 때는 클래스가 유용하다.

 

  • 상속을 모델링하고 행동을 공유하기 위해 구조 및 프로토콜 사용

구조와 클래스는 모두 상속 형식을 지원합니다. 구조와 프로토콜은 프로토콜만 채택할 수 있습니다. 클래스에서 상속할 수 없습니다. 그러나 클래스 상속으로 구축할 수 있는 상속 계층의 종류는 프로토콜 상속 및 구조를 사용하여 모델링할 수도 있습니다.

 

상속 관계를 처음부터 구축하는 경우 프로토콜 상속을 선호합니다. 

프로토콜을 사용하면 클래스, 구조 및 열거형이 상속에 참여할 수 있지만 클래스 상속은 다른 클래스와만 호환됩니다. 

데이터를 모델링하는 방법을 선택할 때 먼저 프로토콜 상속을 사용하여 데이터 유형의 계층 구조를 구축한 다음 구조에서 해당 프로토콜을 채택하십시오.