원본의 복사본을 가진 독립 인스턴스를 가지고 있다. 즉 함수의 매개변수로 값을 보낼 때나 값을 할당할 때 copy 속성으로 값을 처리한다는 것이다.
인스턴스 생성시 스택에 인스턴스가 저장된다.
🔍 참조 타입(Reference Type)
값 타입과 달리 값이 복사되는 것이 아닌 메모리를 참조한다. 즉 메모리 위치를 전달한다.
인스턴스 생성시 스택에는 힙메모리주소가 저장되고 힙에는 인스턴스가 저장된다.
그리고인스턴스는스택에생성된메모리에연결된다. 값타입과달리인스턴스에바로접근할수가없고항상 스택을 거쳐서 접근하는게특징이다.
참조 타입을 예시와 함께 이해해볼까?
class ReferenceClass {
var number: Int = 0
}
let A = ReferenceClass()
A.number = 20
let B = A
B.number = 30
let C = ReferenceClass()
print(A.number, B.number, C.number) // 30 30 0
print(A === B, A !== C) // true true
여기서 B상수가 A의 인스턴스를 복사한 것이 아닌 참조한 것이다.
B는 A가 가리키고 있는 메모리 주소를 가리키고 있다.
상수로 선언했어도 값이 바뀌는 이유는 B 자체를 변경한 것이 아닌 B가 바라보는 값을 변경하는 것이기 때문에 가능하다.
🔍 항등연산자란?
상수와 변수가 같은 인스턴스를 참조하고 있는지 비교하기 연산자
=== : 두 상수나 변수가 같은 인스턴스를 참조하고 있는 경우 참 !== : 두 상수나 변수가 다른 인스턴스를 참조하고 있는 경우 참
✔️ Struct(값 타입)를 사용하는 경우
Swift는 다음 조건중 하나 이상에 해당한다면 구조체를 사용하는 것을 권장한다.
연관된 간단한 값의 집합을 캡슐화 하는 것만이 목적일 때
캡슐화한 값을 참조하는 것보다 복사하는 것이 합당할 때
구조체에 저장된 프로퍼티가 값 타입이며 참조하는 것보다 복사하는 것이 합당할 때
다른 타입으로부터 상속받거나 자신을 상속할 필요가 없을 때
자, 이제 문법을 익혀보자 !
✔️ Struct
struct 구조체는 값(value)타입 이다. 이름은 대문자 카멜케이스를 사용하여 정의한다.
Swift의 대부분타입은구조체로이루어져있다.
// 형태
struct StructName {
/* 프로퍼티와 메서드들 */
}
// 인스턴스 생성
let structInstance = StructName()
✔️ Class
class 클래스는 참조 타입(reference)이다. 이름은 대문자 카멜케이스를 사용하여 정의한다.
Swift의클래스는다중상속이되지않는다.
// 형태
class ClassName {
/* 프로퍼티와 메서드들 */
}
// 인스턴스 생성
let classInstance = ClassName()
✔️ 프로퍼티 및 메서드 구현
var mutable = 5 // 가변 프로퍼티
let immutable = 10 // 불변 프로퍼티
static var type = 15 // 타입 프로퍼티
func instance() { // 인스턴스 메서드
print("I’m instanceMethod")
}
static func typeMethod() { // 타입 메서드, 재정의 불가
print("I’m typeMethod")
}
class func classMethod() { // 타입 메서드, 재정의 가능, 클래스에서만 사용 가능
print("I’m classMethod")
}
이렇게 보니.. 문법적으로는 둘다 비슷한 것 같은데 뭐가 다른걸까?
✔️ class와 struct의 차이점
struct는 값 타입, class는 참조 타입
struct는 상속할 수 없다.
타입캐스팅은 class의 인스턴스에만 허용된다. (상위 또는 하위 클래스 타입으로 형변환 가능)
Deinitializers는 class의 인스턴스에만 활용할 수 있다.
참조 횟수 계산은 class의 인스턴스에만 적용된다.
✔️ class와 struct의 공통점
여러 변수를 담을 수 있는 컨테이너
데이터를 용도에 맞게 묶어 표현하고자 할때 용이하다.
프로퍼티와 메서드를 사용하여 구조화된 데이터와 기능을 가진다
하나의 새로운 사용자 정의 데이터 타입을 만들어 주는 것이다.
초기화를 정의하여 초기 상태를 설정할 수 있다.
확장(extension)하여 프로퍼티나 메소드를 추가할 수 있다.
프로토콜 사용이 가능하다.
서브스크립트(subscript) 사용이 가능하다.
“.”을 이용해 하위 프로퍼티에 접근이 가능하다.
👩🏻🔧 그래서 구조체와 클래스 중 어떤걸 사용하면 좋을까?
속도 : 참조 타입은 참조 추적에 비용이 많이 든다. 값 타입은 시스템 리소스가 적게 들어간다.
안전성 : 클래스는 참조 타입이기 때문에 멀티쓰레드 환경에서 여기저기 참조하여 작업하면 데이터가 꼬일 가능성이 크다.
따라서애플은가급적으로값형식인구조체나열거형을사용하는것을권장한다.
✔️Swift에서의 사용
Swift의 기본 데이터 타입은 모두 구조체로 구현되어 있다.
Swift는 구조체와 열거형 사용을 선호한다.
Apple 프레임워크는 대부분 class를 사용한다.
구조체와 클래스 선택과 사용은 나의 몫.
✔️Apple이 권장하는 클래스와 구조체 용도
연관된 간단한 값의 집합을 캡슐화하는 것만이 목적일 때 구조체를 사용
캡슐화한 값을 참조하는 것보다 복사하는 것이 합당할 때 구조체를 사용
구조체에 저장된 프러파티가 값 타입이며 참조하는 것보다 복사하는 것이 합당할 때 구조체를 사용