Class와 Struct
클래스와 스트럭트의 선택은 직접 필요성을 느끼지 않으면 와닿지 않는 것 같습니다.
오늘 이에 대해서 다시 한 번 정리해보려고 합니다.
Class? Struct?
데이터 구조를 설계할 때 Class와 Struct 사이에서 고민하는 일이 많아졌습니다. 지금까지 알고 있던 지식만으로는 사실 정확하게 판단이 힘들었습니다.
어떤 상황에서 구조체와 클래스를 사용해야 하는지에 대해 여러 의문점이 들어서 다시 한 번 정리를 해보려고 합니다.
참고
[Apple 공식 문서: Structures and Classes]
[Apple 공식 문서: Choosing Between Structures and Classes]
Class와 Struct의 공통점
문서에서도 말하듯 둘은 매우 유사합니다. 이들의 공통점은 무엇일까요?
- 프로퍼티를 정의할 수 있다.
- 메서드를 정의할 수 있다.
- 서브스크립트를 정의할 수 있다.
- 이니셜라이저를 정의할 수 있다.
- Extension으로 기능 확장이 가능하다.
- 프로토콜을 준수할 수 있다.
기본적인 공통점이 존재합니다. 그렇다면 차이점은 무엇일까요?
Class와 Struct의 차이점
다음은 구조체의 특징입니다.
- 멤버와이즈 이니셜라이저를 가진다.
- 값 타입이다.
다음은 클래스의 특징입니다.
- 상속이 가능하다.
- 참조 타입이다.
- 타입 캐스팅으로 런타임 중 타입을 해석할 수 있다.
- 디이니셜라이저를 통해 리소스를 해제한다.
- 참조 카운팅으로 참조를 허용한다.
이처럼 상속과 참조 방식으로 인한 차이점이 돋보입니다.
구조체의 사용성
구조체는 값 타입으로, 앱의 흐름 내에서 구조체에 대한 지역적 변경사항이 앱의 나머지 부분에 영향을 끼치지 않습니다. 즉, 구조체 인스턴스에 대한 변경은 관련 없는 메서드 호출로 인해 이루어지기보다 섹션 내의 명시적인 변경으로 인해 이루어집니다.
Apple 문서에서는 기본적으로는 Struct를 사용하라고 안내하고 있습니다.
인스턴스에게 identity가 필요하지 않을 때
만약 인스턴스의 변경이 지역적으로 이루어져야 하고, 인스턴스에 대한 변경이 실제 값에 영향을 주지 않으려면 Struct를 사용해야 합니다.
예를 들어 데이터베이스 요청으로 인해 레코드가 변경되지 않도록 하는 것과 유사합니다.
클래스의 사용성
Objective-C와의 상호 운용성
Objective-C와의 상호 운용성이 필요한 경우 클래스를 사용해야 합니다.
앱 개발 시에 Objevtive-C로 작성된 API 또는 프레임워크를 사용하게 될 수도 있습니다. 가장 대표적인 예시는 UIKit입니다. UIView의 경우 결국에는 NSObject로 Objective-C 기반으로 작성되었기 때문에, 이를 사용하거나 서브클래싱해서 사용하는 경우 Class를 사용할 수 밖에 없는 것입니다.
또한 Core Data를 사용할 때 이는 Objective-C 기반의 프레임워크이므로 모델을 선언할 때 class를 사용해줍니다.
인스턴스에게 identity가 존재할 때
클래스 인스터스는 참조만 존재한다면 코드 어디서든 인스턴스에 변화를 가하는 것이 가능하므로, identity가 존재한다고 볼 수 있습니다. 즉, 동일한 값을 지닌 인스턴스라도 다르게 취급되고, 객체를 참조할 때는 객체의 위치를 참조하는 것입니다.
예를 들어, 데이터베이스에 대한 완전한 제어가 필요한 경우 class를 사용하는 것이 적합합니다. (데이터베이스는 하나만 존재하며, 모든 코드가 동일하게 참조하고 변경되는 결과를 받아야하므로)
다시 말해 객체가 여러 곳에서 참조되며 변경 사항이 즉시 반영되어야 하는 경우를 말합니다.
결론
클래스와 구조체가 가진 특성을 기반으로 상황에 맞게 잘 사용하는 것이 중요할 것 같습니다. 🙂