Notice
Recent Posts
Recent Comments
Link
大器晩成
지연 저장 속성 (Lazy Stored Properties) 본문
지연 저장프로퍼티(Lazy Stored Property)
- 일반적으로 저장 프로퍼티는 클래스 인스턴스가 처음 생성될 때 함께 초기화되지만, 저장프로퍼티 정의 앞에 lazy키워드가 붙으면 예외입니다.
- lazy키워드가 붙은 프로퍼티는 선언만 될 뿐 초기화되지 않고 계속 대기하고 있다가 프로퍼티가 호출되는 순간에 초기화됩니다. 만약 이 프로퍼티에 클래스나 구조체 인스턴스가 대입된다면, 프로퍼티가 호출되기 전까지는 해당 인스턴스는 초기화되지 않습니다.
- 호출되기 전에는 선언만 된 상태로 대기하다가 실제로 호출되는 시점에서 초기화가 이루어지는 저장 프로퍼티를 지연 저장 프로퍼티라고 합니다.
struct Dog {
var name: String
lazy var weight: Double = 10.0 //선언 및 초기화
init(name: String) {
self.name = name
//self.weight = 0.2 // name처럼 초기화 하지 않은 상태에는 생성자내애서 초기화 불가능.
}
func sit() {
print("앉습니다.")
}
}
var aDog = Dog(name: "강아지") // weight 속성 초기화 안됨
aDog.weight // <======== 해당 변수에 접근하는 이 시점에 초기화됨 (메모리 공간이 생기고 숫자가 저장됨)
//aDog.weight = 20.0 // 가능
//print(aDog.weight)
위의 weight이라는 속성은 초기화 시점에 메모리 공간이 생기는 것이 아님
예를 들어, 인스턴스가 생기고 난 후, aDog.weight 이렇게 접근하는 순간 메모리 공간을 만들고 숫자를 저장 하게됨
- 지연 저장 속성은 "해당 저장 속성"의 초기화를 지연시키는 것입니다.
- 인스턴스가 초기화되는 시점에 해당 속성이 값을 갖고 초기화되는 것이 아닙니다.(메모리에 공간과 값을 갖지 않습니다.)
- 해당 속성(변수)에 접근하는 순간에 (해당 저장 속성만) 개별적으로 초기화됩니다.
-> 따라서, 상수로의 선언은 안되고 변수(var)로의 선언만 가능 ➡︎ lazy var만 가능(lazy let 불가능) - 지연 저장 속성은 "선언시점에 기본값을 저장" 해야합니다.
- 지연 저장 속성은 구조체와 클래스 모두 동일합니다.
- 값을 넣거나, 표현식(함수 실행문)을 넣을 수 있습니다.
- 모든 형태의 표현식 - 함수 호출코드, 계산코드, 클로저 코드 등 모두 가능합니다.
-> 저장하려는 속성과 "리턴형"만 일치하면 됩니다. - 메모리 공간에 없다가 처음접근 하는 순간에 (해당 속성만) 개별적으로 초기화됩니다.
클로저를 이용한 저장 프로퍼티 초기화
let/var 프로퍼티명: 타입 = {
정의 내용
return 반환값
}()
//이렇게 정의된 클로저 구문은 클래스나 구조체의 인스턴스가 생성될 떄 함께 실행되어 초기값을 반환하고,
//이후로는 해당 인스턴스 내에서 재실행되지 않는다.
class PropertyInit {
//저장 프로퍼티 - 인스턴스 생성 시 최초 한 번만 실행
var value01: String! = {
print("value01 execute")
return "value01"
}()
//저장 프로퍼티 - 인스턴스 생성 시 최초 한 번만 실행
var value02: String! = {
print("value02 execute")
return "value02"
}()
lazy var value03: String! = {
print("value03 execute")
return "value03"
}()
}
let s = PropertyInit() //클로저 구문을 이용하여 초기화하기 때문에 print문이 출력된다. (value03은 제외)
//value01 execute
//value02 execute
// 저장 프로퍼티를 단순히 참조만 하면 새로운 로그도 출력되지 않는다,
s.value01 = {"Hello"}()
print(s.value01) // Optional(Hello)
s.value02
//실제로 참조하는 시점에 실행될 수 있도록 정의하는 방법 lazy 사용
lazy let/var 프로퍼티명: 타입 = {
정의 내용
return 반환값
}()
let s1 = PropertyInit()
s1.value03 // value03 execute 실행
s1.value03 // 실행결과 없음
- 저장프로퍼티 중의 일부는 연산이나 로직 처리를 통해 얻어진 값을 이용하여 초기화해야 하는 경우가 있습니다. 스위프트에서는 이와 같은 경우 클로저를 사용하여 필요한 로직을 실행한 다음, 반환되는 값을 이용하여 저장 프로퍼티를 초기화할 수 있도록 지원합니다.
- lazy 키워드를 붙여서 정의한 저장 프로퍼티를 클로저 구문으로 초기화하면 최초 한 번만 로직이 실행되는 데다 실제로 참조되는 시점에 맞추어 초기화되기 때문에 메모리 낭비를 줄일 수 있습니다.
지연 저장 속성을 사용하는 이유
@MainActor // UIImageView 에러방지
class AView {
var a: Int
// 1) 메모리를 많이 차지할때
lazy var view = UIImageView() // 객체를 생성하는 형태
// 2) 다른 속성을 이용해야할때(다른 저장 속성에 의존해야만 할때)
//var b = a * 10 // 오류
lazy var b: Int = {
return a * 10
}()
lazy var c = a * 20
init(num: Int) {
self.a = num
}
}
var test = AView(num: 10)
test.b // 100
test.c // 200
- 메모리 공간을 많이 차지하는 이미지 등의 속성에 저장할 때
- 반드시 메모리에 다 올릴 필요가 없으므로 지연 저장 속성으로 선언하는 경우가 있습니다. (메모리 낭비 막기 위함) - 다른 속성 또는 메서드들을 이용해야 할 때
- 초기화 시점에 모든 속성들이 동시에 메모리 공간에 저장되므로 어떤 한 가지 속성이 다른 속성이나 메서드에 접근할 수가 없습니다.
- 지연 저장 속성을 이용하는 경우 지연으로 저장된 속성은 먼저 초기화된 속성이나 메서드에 접근할 수 있게 됩니다.
728x90
'iOS > Swift 문법' 카테고리의 다른 글
| 타입속성 (Type Properties) (0) | 2024.11.22 |
|---|---|
| 계산/연산 속성(Computed property) (0) | 2024.11.22 |
| 저장속성(Stored Properties) (0) | 2024.11.21 |
| 초기화(initializer) (0) | 2024.11.21 |
| 클래스와 구조체의 차이 (0) | 2024.11.21 |