클래스, 구조체, 열거형과 관련한 값
Swift에서는 3가지 형태로 존재하는데 바로 저장 프로퍼티, 연산 프로퍼티, 타입 프로퍼티로 구성됨
클래스와 구조체에서만 사용할 수 있고, 값을 저장하기 위해 선언되는 상수/ 변수
우리가 지금까지 흔히 본 케이스로 let, var을 통해서 선언 가능함!
열거형에서 사용불가❌class Human { let name: String = "hidi" var age: Int = 23 } struct Person { let name: String = "hidi" var age: Int = 23 }
Q. 인스턴스를 let으로 선언했는데 왜.. age가 var로 선언되어도 변경가능한지?
A. 스택에 있는 hidi은 힙 영역에 있는 인스턴스를 참조하고 있는 형태 (다들 알죠?)
스택에는 only 힙에 할당된 인스턴스의 주소값밖에 없다..
let hidi: Human? = .init()
hidi?.name = "hidi" // 에러
hidi?.age = 24 // 가능!
//따라서 인스턴스 값 자체에 nil이 들어가는 건 안됨
hidi = nil // error
A. 다 가능 ㅋㅋ nil도 가능하고, 다른 Instance 대입도 되고
단. 상수로 선언된 프로퍼티 변경은 불가능하겠죠?
Q. 왜.. age가 var로 선언되어도 변경이 안되죠...?
A. 구조체는 값타입!! 그렇기 때문에 모든 프로퍼티가 스택에 저장됨
따라서 구조체 인스턴스를 let으로 선언한 순간 구조체의 모든 멤버는 변경불가!
let hidi: Human? = .init()
hidi?.name = "hidi" // 에러!
hidi?.age = 24 // 에러!
//당연히 인스턴스 값 자체에 nil이 들어가는 건 안됨
hidi = nil // error
A. 다 가능 ㅋㅋ nil도 가능하고, 다른 Instance 대입도 되고
단. 상수로 선언된 프로퍼티 변경은 불가능하겠죠?
프로퍼티가 호출되기 전까지는 선언만 될 뿐 초기화되지 않고 있다가, 프로퍼티가 호출되는 순간에 초기화되는 저장 프로퍼티
프로퍼티 앞에 lazy 키워드를 붙여서 사용한다!
자 우리가 기존에 알고있던 초기화의 상식은..
초기화 구문이 불리는 순간 모든 프로퍼티가 초기화가 되어야 했다!!! (저번주꺼 참고~)
그래서 초기화 구문 바로 실행띠~!
class Sopt {
var part: String = ""
var generation: String = ""
init() { print("안녕 난 Sopt인") }
}
class Human {
var name: String = "unKnown"
var sopt: Sopt = .init()
// 클래스 인스턴스를 초기화를 하면
let hidi: Human = .init()
// 결과로
"안녕 난 SOPT인"
but lazy 키워드를 붙여서 선언을 한다면...
선안만 될 뿐, 변수 자체가 초기화되지 않아서 변수에 처음으로 접근할 때
초기화 구문 발동~!
class Sopt {
var part: String = ""
var generation: String = ""
init() { print("안녕 난 SOPT인") }
}
class Human {
var name: String = "unKnown"
lazy var sopt: Sopt = .init()
// 클래스 인스턴스를 초기화를 하면
let hidi: Human = .init()
// 결과로 암것도 안나옴 => lazy로 인한 지연
// 따라서 contacts란 변수에 처음으로 접근하고자 할때
hidi.contacts.part = "iOS"
// 결과로
"안녕 난 SOPT인"
- 인스턴스 초기화와 상관없이, 처음 사용될 때 개별적으로 초기화 된다! (위에서 본 내용)
- 따라서 항상 var(변수)로 선언되어야 한다!
why? let으로 서언되면 우리가 필요한 시점에 초기화를 진행할 수 없기 때문!
- 특정 요소에 의존적이어서 그 요소가 끝나기 전에 적절한 값을 알지 못하는 경우에 유용합니다.
- 복잡한 계산이나 부하가 많이 걸리는 작업 => 실제 사용되기 전에는 실행되지 않아서 인스턴스의 초기화 시점에 복잡한 계산을 피할 수 있습니다.