Swift - 클래스와 구조체란?
Swift - 클래스와 구조체란?
클래스와 구조체란?
- 변수나 상수를 선언하고 함수를 정의하여 사용할 수 있도록 묶어주는 사용자 정의 타입
- 프로퍼티: 클래스나 구조체 내부에 선언된 변수나 상수
- 메서드: 클래스나 구조체 내부에 정의된 함수
클래스 정의 구문
1
2
3
4
5
class 클래스명{
// 프로퍼티...
// 메서드...
}
구조체 정의 구문
1
2
3
4
5
struct 구조체명{
// 프로퍼티..
// 메서드..
}
예시
1
2
3
4
5
6
7
8
9
10
11
12
class Person{
var name = ""
var age: Int?
}
struct Animal{
var name: String
var age: Int
}
var person = Person()
var animal = Animal(name: "뽀삐", age: 3)
클래스의 경우 프로퍼티에 초기값 지정, 옵셔널 선언, 초기화 구문 사용을 통해 값을 할당해주지 않으면 오류가 발생하게 됨.
초기화 구문 사용 예시
1
2
3
4
5
6
7
8
9
10
11
class Person{
var name: String
var age: Int?
init(name: String, age: Int? = nil) {
self.name = name
self.age = age
}
}
var person = Person(name: "홍길동", age: 20)
옵셔널 선언 예시
1
2
3
4
5
6
class Person{
var name: String?
var age: Int?
}
var person = Person()
옵셔널 선언에 경우 초기 값이 nil로 자동으로 할당됨.
초기값 할당 예시
1
2
3
4
5
6
class Person{
var name: String = "홍길동"
var age: Int = 20
}
var person = Person()
구조체의 경우 초기값, 옵셔널 선언을 하지 않더라도 자동으로 모든 프로퍼티를 초기화할 수 있는 초기화 구문을 제공해줌.
예시
1
2
3
4
5
6
struct Animal{
var name: String
var age: Int
}
var animal = Animal(name: "뽀삐", age: 3)
클래스와 구조체의 공통점
- 프로퍼티: 클래스나 구조체 내 선언된 변수나 상수
- 메서드: 클래스나 구조체 내 선언된 함수
- 서브스크립트: 인스턴스에 접근할 수 있도록 하는 방법 정의 가능
- 초기화: 객체 초기 상태를 지정하는 초기화 블록 정의 가능
- 확장:
extension구문 사용 가능 - 프로토콜: 프로토콜을 채택할 수 있음
클래스와 구조체의 차이점
구조체와 클래스는 겉보기엔 유사하지만 클래스가 제공하는 부가 기능이 더 많음.
- 상속: 클래스의 특성을 다른 클래스에게 물려줄 수 있음
- 타입 캐스팅: 컴파일러가 클래스 인스턴스의 타입 미리 파악하고 검사 가능
- 소멸자: 인스턴스가 소멸되기 전 처리해야할 구문 등록 가능
- 구조체는 값 타입, 클래스는 참조 타입
값에 의한 전달?
- 변수나 상수에 구조체를 할당했을 때 구조체 내부에 값 자체가 복사됨.
- 구조체 프로퍼티 값을 수정하더라도 원본 구조체에는 영향이 없음.
- 구조체는 값에 의한 전달이 일어남.
예시
1
2
3
4
5
6
7
8
9
10
11
struct Person{
var name: String
var age: Int
}
var person1 = Person(name: "Hong", age: 20)
var person2 = person1
person2.age = 30
print(person1)
print(person2)
결과
1
2
Person(name: "Hong", age: 20)
Person(name: "Hong", age: 30)
참조에 의한 전달?
- 클래스는 구조체와 달리 구조체 값 자체가 복사되는 것이 아닌 저장된 메모리 주소가 할당됨.
- 이 경우엔 값을 수정할 경우 원본 데이터에도 영향이 있음.
예시
1
2
3
4
5
6
7
8
9
10
class Animal{
var gender: String = "수컷"
var name: String = "길냥이"
}
let animal1 = Animal()
let animal2 = animal1
animal2.name = "길멍이"
print(animal1.name)
print(animal2.name)
결과
1
2
길멍이
길멍이
하지만 이것은 구조체와 달리 메모리 주소가 복사되는 것이기 때문에 어디서 참조되고 있는지 일일이 확인하기 어렵고, 메모리를 어느 시점에 해제해줘야하는지도 파악하기 힘듬.
이런 문제를 해결하기 위해 Swift는 ARC(Automatic Reference Counting)를 제공해줌.
ARC(Automatic Reference Counting)
- 클래스 인스턴스를 참조 중인 곳이 몇 군데인지를 자동을 카운트해줌.
- 인스턴스를 모니터링하면서 변수, 상수, 함수의 매개 변수로 전달되면 카운트를 1 증가시키고, 사용이 종료되면 카운트를 1 감소시킴.
- 이때 카운트가 0이 된 인스턴스는 메모리에서 해제시킴.
인스턴스 비교
- 일반적으로 비교 연산에 사용되는
==연산자는 클래스 인스턴스에는 사용할 수 없음.- 값을 비교하는 것이 아닌 메모리 주소가 일치하는지를 확인해야하기 때문임.
- 인스턴스는
===연산자를 통해 비교를 처리해야함.
예시
1
2
3
4
5
6
7
8
9
10
11
12
13
class Animal{
var gender: String = "수컷"
var name: String = "길냥이"
}
let animal1 = Animal()
let animal2 = animal1
if animal1 === animal2{
print("동일 인스턴스")
}else{
print("동일하지 않은 인스턴스")
}
결과
1
동일 인스턴스
구조체 인스턴스는
==를 사용할 수 있지만, 클래스의 경우Equatable프로토콜을 채택하면 클래스 인스턴스에서도==연산자 사용이 가능함.
This post is licensed under CC BY 4.0 by the author.