본문 바로가기

iOS & Swift

Swift - lazy 키워드

요즘은 프로젝트를 리팩토링 하면서, 아쉬웠던 부분을 수정해보고 있습니다.

코드 기반 UI를 구성 할 때, 습관적으로 view 요소를 lazy var 로 선언하고 있더라구요.. 그래서 오늘은 lazy 키워드에 대해 알아보려고 합니다.


Lazy 키워드?

애플 공식문서에서는 “lazy 저장 변수는 이것이 처음 사용되기 전까지 초기값이 계산되지 않는 프로퍼티 입니다. 사용자는 선언부에 lazy 수정자를 붙임으로써 lazy 저장 변수를 나타낼 수 있습니다” 라고 소개하고 있습니다.

lazy 변수는 처음 호출 될 때 초기화가 되며, 메모리에 올라간다고 합니다. 할당이 최초 호출 될 때로 늦출 수 있어 지원 저장 프로퍼티라고 불리는거 같습니다.

자세히 살펴보기 위해 예제를 통해 동작을 한번 확인하시죠.

import Foundation

struct NameLabel {
    var name: String
    lazy var lazyLabelContent: LabelContent = {
        return LabelContent(self.name)
    }()
    
    var computedLabelContent: LabelContent {
       return LabelContent(self.name)
    }
    
    init(_ name: String) {
        self.name = name
    }
}

struct LabelContent {
    var content: String
    
    init(_ name: String) {
        print("\(name)'s LabelContent initialize ")
        self.content = "Hello My Name is \(name)"
    }
}

var lazyNameLabel = NameLabel("Kim Cook") 
print(lazyNameLabel.lazyLabelContent)
// Kim Cook's LabelContent initialize 
// LabelContent(content: "Hello My Name is Kim Cook")
lazyNameLabel.name = "Cook Kim"
print(lazyNameLabel.lazyLabelContent) //LabelContent(content: "Hello My Name is Kim Cook")

lazy 키워드 같은 경우 최초에는 값이 없다가, 호출 시 값이 초기화 되는것이기 때문에, var로 항시 선언해줘야 합니다. let 으로 선언시 컴파일 오류가 발생합니다.

var lazyNameLabel = NameLabel("Kim Cook")에서 NameLabel이 초기화 될 때, lazyLabelContent의 값은 정해지지 않습니다.

print(lazyNameLabel.lazyLabelContent)에서 호출되어서 비로소 lazyLabelContent 초기화되는 것을 확인 할 수 있습니다.

이후 name 을 변경하여도 후 print(lazyNameLabel.lazyLabelContent) 다시 호출하여도 최초 할당이 되었기 때문에 변화가 없는 것을 볼 수 있습니다.

비슷한 computed 프로퍼티 동작을 보시죠!

var computedNameLabel = NameLabel("Kim Cook")
print(computedNameLabel.computedLabelContent)
// Kim Cook's LabelContent initialize 
// LabelContent(content: "Hello My Name is Kim Cook")
computedNameLabel.name = "Cook Kim"
print(computedNameLabel.computedLabelContent)
// Cook Kim's LabelContent initialize 
// LabelContent(content: "Hello My Name is Cook Kim")

당연하지만, 호출 될 때마다 정의 된 클로저에 따라 반환이 되기 때문에, 초기화가 동작하는 걸 볼 수 있습니다.

lazy의 값에 대한 느낌이 오셨나요? lazy를 언제 적재적소에 활용하는 것이 좋을까요?

Lazy 활용 용도

어느 view에나 lazy var로 선언한 저와 달리 언제 유의미하게 사용해야할까?!? 고민을 해봤습니다…

제가 생각 했을 때 두 가지 경우에 활용하는 것이 좋을거 같습니다.. 개인적인 견해이므로 여러 의견이나 피드백 주시면… 정말 감사하겠습니다.

• 특이 case로 인해 발생하는 값인 경우, 가입 된지 3개월 미만인 신규유저에게만 보여지는 뷰 또는 기능

• 다른 값에 의존이 되어 의존 된 값이 결정 된 이후 초기화가 필요한 경우

무의미한 코드 작성은 가독성에 혼란을 줄 수 있습니다…


참고

https://levenshtein.tistory.com/484

https://hyunndyblog.tistory.com/155