swift

swift - Property #1 (Stored Properties, Explicit Member Expression, Lazy Stored Properties)

행복하게사는게꿈 2021. 1. 12. 10:59

// 저장속성 : 형식 내부에 속성을 설정한다.
// 저장속성은 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