오늘은 구조체와 클래스를 비교해보려고 합니다!
1. 구조체와 클래스의 비교
먼저 구조체와 클래스의 공통점은 다음과 같은데요!
구조체와 클래스의 공통점
- 값을 저장하는 프로퍼티 정의
- 기능 제공을 위한 메서드 정의
- 서브 스크립트 구문을 사용하여 값에 접근을 제공하는 서브 스크립트 정의
- 초기화 상태를 설정하기 위한 초기화 정의
- 기본 구현을 넘어 기능적 확장을 위한 확장
- 특정 종류의 표준 기능을 제공하는 프로토콜 준수
서브 스크립트는 익숙하지 않은 개념이라 다음에 포스팅 해보려고 합니다!
차이점은 다음과 같습니다!
구조체와 클래스의 차이점
구조체 (Struct)
- 값타입
- 변수 또는 상수에 할당될 때나 함수에 전달될 때 값이 복사
- 열거형도 값 타입이다.
클래스 (Class)
- 참조타입
- 변수 또는 상수에 할당될 때나 함수로 전달될 때 복사되지 않음
- 복사 대신 같은 인스턴스에 대한 참조가 사용됨
- ARC로 메모리 관리
- 상속 가능
- 타입 캐스팅을 통해 클래스의 인스턴스 타입 확인 가능
- deinit을 사용하여 클래스 인스턴스의 메모리 할당 해제 가능
가장 큰 차이점은 구조체(Struct)는 값타입이고 클래스(Class)는 참조타입이라는 것을 알 수 있네요!
예시를 들어서 비교를 해보겠습니다.
struct Resolution {
var width = 0
var height = 0
}
class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name: String?
}
Resolution이라는 Struct와 VideoMode라는 Class를 선언해주었습니다.
let hd = Resolution(width: 1920, height: 1080)
var cinema = hd
cinema.width = 2048
그 다음 hd라는 상수를 선언하고 Resolution 인스턴스를 설정합니다.
그 다음에 cinema 라는 변수를 선언하고 hd의 현재 값을 설정하는 것을 볼 수 있죠!
이때 기존 인스턴스가 복제되어 cinema에 할당이 되게 되는데, 인스턴스가 복제가 되었기 때문에 cinema 인스턴스의 프로퍼티를 수정하더라도 hd 인스턴스의 프로퍼티에는 아무런 영향이 없습니다!
위 코드를 그림으로 살펴보면 다음과 같습니다.
cinema에 hd 의 값을 설정할 때 값이 복사가 되어 별개의 메모리 공간을 가지기 때문에 cinema의 프로퍼티가 변해도 hd에는 영향을 끼칠 치지 않는 것을 볼 수 있네요!
그 다음 Class에서 인스턴스의 참조를 살펴보겠습니다!
let tenEighty = VideoMode()
tenEighty.resolution = hd
tenEighty.interlaced = true
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0
let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0
tenEighty라는 상수를 선언하고 VideoMode 클래스의 인스턴스를 생성하면서 참조하도록 했습니다.
해당 인스턴스의 프로퍼티들의 값을 초기화 해줬구요!
그 다음 alsoTenEighty 라는 새로운 상수를 선언하고, tenEighty라는 인스턴스를 참조하도록 했습니다.
이후 상수 alsoTenEighty 의 인스턴스 중 하나인 frameRate를 30.0으로 바꾸어줬는데요! 이 경우 tenEighty와 alsoTenEighty는 같은 인스턴스를 참조하고 있기 때문에 둘 중 하나에서 인스턴스를 바꾸더라도 양쪽 다 반영이 되게 됩니다!
이를 그림으로 살펴보면 다음과 같습니다.
tenEighty와 alsotTenEighty 둘 다 같은 인스턴스를 참조하고 있기 때문에 하나가 바뀌면 공통으로 참조하고 있는 인스턴스가 바뀌기 때문에 각각의 상수에서 인스턴스에 접근했을 때 동일한 값을 나타내게 됩니다!!
식별 연산자 (Identity Operators)
그래서 만약 어떤 변수나 상수가 같은 인스턴스를 참조하고 있는지 확인하기 위한 방법으로 식별 연산자가 있습니다.
- 동일 인스턴스 (Identical to) (===)
- 동일하지 않은 인스턴스 (Not identical to) (!==)
위 예시 코드를 통해서 예를 들어보자면
let isIdentical = tenEighty === alsoTenEighty
// isIdentical = true
가 되는거죠!
메모리 할당 위치
또한 메모리에 할당될 때 구조체와 같은 값타입은 Stack 영역에 할당되고, 클래스와 같은 참조타입은 Heap 영역에 할당이 됩니다!
그래서 Swift에서도 웬만하면 Stack 영역이 안전하고 접근이 빠르기 때문에 Struct를 권장한다고 합니다!
오늘은 간단하게 구조체와 클래스의 공통점과 차이점에 대해서 살펴보았는데, 이것 말고도 엄청 많기 때문에 추후에 또 포스팅을 할 예정입니다!
'Swift' 카테고리의 다른 글
[Swift] Core Data 기본(Core Data Stack과 NSManagedObjectContext) (0) | 2024.11.17 |
---|---|
Electron 앱과 Swift Native 앱간 통신하기 (0) | 2024.09.04 |
[Swift] 서브스크립트(subscript)에 대해 알아보자! (0) | 2024.08.23 |
[Swift] Picker 숫자에 간격 주기 (0) | 2024.08.02 |
[Swift] UIViewController를 SwiftUI에서 사용하는 법 (0) | 2024.08.02 |