// 저장속성 : 형식 내부에 속성을 설정한다.
// 저장속성은 instance
// var : 변수
// let : 상수
class Person {
let name: String = "John Doe"
var age: Int = 33
}
let p = Person()
p.name
p.age
// instance 멤버에 접근하는 . : Dot syntax or Explicit Member Expression
// var로 age를 설정했기 때문에 바꿀 수 있음
p.age = 30
p.age
// p.name = "New Name" 못바꿈
struct Person2 {
let name: String = "Jaeho"
var age: Int = 28
}
let p2 = Person2()
p2.name
p2.age
// 구조체 인스턴스를 let으로 생성하면 내부 멤버변수를 수정할 수 없음
// 즉, 구조체 인스턴스의 var, let에 따라 내부 멤버변수도 영향을 받는다.
// 그러나 인스턴스가 var여도 멤버변수가 let이면 수정 불가능
// p2.age = 30
var p3 = Person2()
p3.age = 30
// name이 let으로 선언되어 있기 때문에 불가능
// p3.name = "new jaeho"
// 지연 저장 속성
// 어떤 것이 지연되는가?
// lazy 키워드를 붙이면 초기화 시점이 지연된다!
// 변수 저장속성을 선언해야 한다. -> let은 사용 불가능
// 생성자를 사용하지 않기때문에 선언시점에 자료형을 할당해야함
struct Image {
init() {
print("new Image")
}
}
struct BlogPost {
let title: String = "Title"
let content: String = "Content"
let attachment: Image = Image()
}
let post = BlogPost()
// 지금처럼 attachment를 저장속성으로 설정하면 Image instance를 생성할때마다 생성됨 -> 사실 image속성은 메모리 할당량이 크기 때문에 오버헤드 발생가능성이 있다.
// attachment속성을 항상 사용한다면 어쩔 수 없지만 항상 사용하는 것이 아니라면 접근할때 초기화되는 lazy 키워드를 사용하자
struct BlogPost2 {
let title: String = "Title"
let content: String = "Content"
lazy var attachment: Image = Image()
let date: Date = Date()
// 여기서 lazy를 안붙이면 date와 formattedDate 속성이 동시에 초기화 되기 때문에 return f.String()에서 date 변수를 사용하지 못함
// lazy를 붙이면 date가 항상 먼저 초기화되기 때문에 사용 가능하다
lazy var formattedDate: String = {
let f = DateFormatter()
f.dateStyle = .long
f.timeStyle = .medium
return f.string(from: date)
}() // 여기서 핵심은 () : 만약 ()를 빼면 파라미터가 없고 리턴형이 String인 클로저가 String에 저장되는건데 ()를 붙이면 클로저가 리턴하는 값이 저장된다.
}
var post2 = BlogPost2()
// attachment라는 속성에 처음 접근할때 초기화 된다.
post2.attachment