구조체와 클래스는 데이터를 용도에 맞게 묶어 표현하고자 할 때 유용하다. 프로퍼티와 메서드를 사용하여 구조화된 데이터와 기능을 가질 수 있다.
Struct 의 특징을 알아보자.
- 값 타입이다. 값의 타입을 정의하기 위해 사용된다.
- 대입 명령 시 내용이 복사된다.
- 참조 카운트가 없어서 메모리 관리에 안전하다.
- 레퍼런스 형태가 아니기 때문에 공유가 불가능하다.
- 불변성(Immutable) 구현에 유리하다.
- 멀티스레딩에 안전하다.
- 상속이 불가능하다.
- 프로토콜은 사용이 가능하다.
- Object가 아니기 때문에 AnyObject로 캐스팅이 안된다. -> 기존의 id 로 쓰던 타입들을 모두 AnyObject 로 받는 경우가 많은데 이 경우 struct 로 만들어진 값을 넘기는게 불가능하다는 의미가 된다. 대신 Any 의 경우는 struct 로 만들어진 값도 캐스팅이 가능하다.
Struct와 Class를 비교할 때 첫 번째 항목인 값과 참조 라는 차이점에 대해 가장 많이 언급한다.
✓ 참조 타입 (Reference Type)
class Animal {
var weight = 0
init(weight: Int) {
self.weight = weight
}
}
var cat = Animal(weight: 10)
var dog = Animal(weight: 20)
cat.weight // 10
dog.weight // 20
cat = dog
cat.weight // 20
dog.weight // 20
dog.weight = 100
cat.weight // 100
dog.weight // 100
cat = dog 코드가 실행이 된 이후로 둘은 하나의 오브젝트처럼 보인다. 이것은 cat = dog 코드가 '레퍼런스 복사'로 동작한다는 것을 의미한다.(둘 다 동일한 메모리 레퍼런스를 가지고 있다는 말.) 이후 cat 이나 dog 의 값을 바꾸게 되면 동일하게 다른 쪽의 값도 바뀌게 된다. 어차피 동일한 메모리의 내용이 바뀌는 것이니까.
✓ 값 타입 (Value Type)
struct Animal {
var weight = 0
init(weight: Int) {
self.weight = weight
}
}
var cat = Animal(weight: 10)
var dog = Animal(weight: 20)
cat.weight // 10
dog.weight // 20
cat = dog
cat.weight // 20
dog.weight // 20
dog.weight = 999
cat.weight // 20
dog.weight // 999
구조체에게 있어서 '=' 연산자의 동작은 값(value)의 복사로 동작하게끔 정의되어 있다.
✓ 생성 속도
메모리에 인스턴스가 생성될 때의 시간을 계산해 봤다.
컴퓨터와 시스템 상태에 따라 값은 다르게 나오지만, 무조건 Struct 가 Class 보다 빠른 걸 확인할 수 있다.
✓ Struct 와 Class 의 공통점
- 값을 저장하기 위해 프로퍼티를 정의할 수 있다.
- 기능 실행을 위해 메서드를 정의할 수 있다.
- 서브스크립트 문법을 통해 구조체 또는 클래스가 갖는 값(프로퍼티)에 접근하도록 서브스크립트를 정의할 수 있다.
- 초기화 될 때의 상태를 지정하기 위해 이니셜라이저를 정의할 수 있다.
- 초기구현과 더불어 새로운 기능 추가를 위해 익스텐션을 통해 확장할 수 있다.
- 특정 기능을 실행하기 위해 특정 프로토콜을 준수할 수 있다.
✓ Struct 와 Class 의 차이점
- 구조체는 상속할 수 없다.
- 타입 캐스팅은 클래스의 인스턴스에만 허용된다.
- 디이니셜라이저는 클래스의 인스턴스에만 활용할 수 있다.
- 참조 횟수 계산은 클래스의 인스턴스에만 적용한다.
✓ 애플은 다음 조건 중 하나 이상에 해당한다면 구조체를 사용하는 걸 권장한다.
- 연관된 간단한 값의 집합을 캡슐화하는 것만이 목적
- 캡슐화 한 값을 참조하는 것 보다 복사하는 것이 합당할 때
- 구조체에 저장된 프로퍼티가 값 타입이며 참조하는 것 보다 복사하는 것이 합당할 때
- 다른 타입으로부터 상속받거나 자신을 상속할 필요가 없을 때
✅ 정리:
1. 상속, 초기화 해제객체, 레퍼런스 카운팅 등 다양한 기능을 제공하는 클래스에 비해 훨씬 제약된 수의 기능을 제공하는 스위프트가 표준 라이브러리의 구성 요소로서 적합하기 때문이다.
2. 구조체는 밸류 타입으로서, 단 하나의 소유 객체만을 지니며, 새로운 변수에 할당하거나 함수에 전달할 때는 항상 복사해서 사용한다는 점도 이유 중 하나다.
구조체의 이런 단순성은 우리가 작성한 코드를 체계적으로 안정화시키며, 특정 구조체를 변경해도 앱의 다른 부분은 영향을 받지 않을 수 있다.
출처: https://docs.swift.org/swift-book/LanguageGuide/ClassesAndStructures.html
출처: iOS 프로그래밍을 위한 스위프트 기초(야곰)
출처: http://seorenn.blogspot.com/2016/04/swift-class-struct.html
'Swift' 카테고리의 다른 글
[Swift] lazy는 왜 쓰는지 아시나요? (0) | 2022.11.09 |
---|---|
[Swift] guard, let 둘의 차이점은? (0) | 2022.11.09 |
[Swift] final 왜 쓰는지 아시나요? (0) | 2022.09.12 |
[Swift] Swift는 왜 상수(let)를 선호할까? (0) | 2022.06.25 |