구조체와 클래스는 OOP를 위한 필수 요소로 프로그램의 코드를 추상화하기 위해 사용합니다.
또한 Swift에서는 다른 프로그래밍 언어와 달리 구조체와 클래스를 위한 별도의 인터페이스와 파일을 만들 필요가 없습니다.
struct [구조체 이름] {
[프로퍼티와 메서드들]
}
class [클래스 이름] {
[프로퍼티와 메서드들]
}
class [클래스 이름]: [부모클래스 이름] {
[프로퍼티와 메서드들]
}
swift에서는 구조체와 클래스 모습과 문법이 거의 흡사하지만 둘은 분명한 차이점이 존재
Struct
인스턴스 : 값 타입
상속이 불가능
Class
인스턴스 : 참조 타입
단일 상속
클래스 인스턴스에만 허용
타입캐스팅
Deinitializer
참조 횟수 계산
애플은 다음 조건 중 하나 이상에 해당한다면 구조체를 사용하는 것을 권장
// String 타입의 기본 정의 코드
public struct String {
/// An empty 'String'.
public init()
}
스위프트의 기본 타입은 모두 구조체로 구현되어 있습니다. 이는 기본 데이터 타입은 모두 값 타입이라는 의미입니다. 따라서, 전달인자를 통해 데이터를 전달하면 모두 값 복사되어 전달될 뿐, 함수 내부에서 아무리 전달된 값을 변경하려고 시도해도 기존의 변수나 상수에는 전혀 영향 미치지 못합니다.
// 프로퍼티 이름(name, age)으로 자동 생성된 이니셜라이저를 사용하여 구조체를 생성합니다.
var yagomInfo: BasicInformation = BasicInformation(name: "yagom", age: 99)
yagomInfo.age = 100 // 변경 가능!
yagomInfo.name = "Bear" // 변경 가능!
// 프로퍼티 이름(name, age)으로 자동 생성된 이니셜라이저를 사용하여 구조체를 생성합니다.
let hanaInfo: BasicInformation = BasicInformation(name: "hana", age: 99)
hanaInfo.age = 100 // 변경 불가!
class Person {
var height: Float = 0.0
var weight: Float = 0.0
}
var yagom: Person = Person()
yagom.height = 123.4
yagom.weight = 123.4
let hana: Person = Person()
hana.height = 123.4
hana.weight = 123.4
class Person {
var height: Float = 0.0
var weight: Float = 0.0
deinit {
print("Person 클래스의 인스턴스가 소멸됩니다.")
}
}
var yagom: Person? = Person()
yagom = nil // Person 클래스의 인스턴스가 소멸됩니다.
위 코드에선 Person 클래스는 프로퍼티의 기본값이 지정되어 있으므로 전달인자를 통해 초깃값을 전달하지 않아도 됩니다.
마찬가지로, 프로퍼티 값에 접근하고 싶을때 → . 사용
참조 타입
구조체와 다르게 클래스 인스턴스는 참조 타입
→ 클래스의 인스턴스를 let으로 선언해도 내부 프로퍼티 값을 변경할 수 있다.
클래스의 인스턴스는 더이상 참조할 필요가 없을때 메모리에서 해제됩니다.
→ 이 과정을 "소멸"
→ 소멸되기 직전 "deinit"라는 메서드가 호출됨
(deinit 메서드 : 디이니셜라이저 ( Deinitializer )라고 부릅니다.)
→ deinit 메서드는 클래스당 하나만 구현 가능
→ 또한, 매개변수와 반환 값을 가질 수 없습니다. ( 소괄호 없음 )
→ 프로그래머가 직접 deinit 메서드를 호출할 수 없다.
deinit 메서드 구현해야 할땐 언제일까?
인스턴스 소멸 전에 데이터를 저장한다거나 다른 객체에 인스턴스 소멸을 알려야 할 때