일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- continue
- 프로그래머스 자동커밋
- 프로그래머스 문자열 정렬하기 (1)
- Til
- 연산자
- 프로그래머스 조건에 맞게 수열 변경하기 3
- 문자열 붙여서 출력하기
- 프로그래머스 암호 해독
- 스페인어
- cocoapods 설치 오류
- 프로그래머스
- 프로그래머스 배열 만들기1
- 주사위 게임1
- 조건에 맞게 수열 변경하기 3
- 프로그래머스 문자열 붙여서 출력하기
- 프로그래머스 n번째 원소까지
- Error installing cocoapods
- Break
- 문자열 정렬하기 (1)
- array
- n번째 원소까지
- 객체지향
- 프로그래머스 n의 배수 고르기
- 배열 만들기1
- ruby설치
- 스파르타코딩캠프
- 스파르타 코딩클럽 내일배움캠프
- swift
- 프로그래머스 최댓값 만들기(2)
- 프로그래머스 주사위 게임1
- Today
- Total
dev._.note
[Swift] lazy란? 본문
lazy란?
lazy 저장 프로퍼티는 처음 사용되지 전까지 초기값이 계산되지 않는 프로퍼티이다. (메모리에 올라가지 않는다.)
변수(var) 앞에 lazy를 선언함으로써 사용할 수 있다.
lazy는 var(변수) 앞에 사용
초기 값은 인스턴스 초기화가 완료 될 때까지 검색되지 않을 수 있기 때문에 변수로 선언해야한다.
상수(let)은 초기화가 완료되기 전에 항상 값을 가지고 있는 상태이어야 하기 떄문에 lazy로 선언할 수 없다.
struct Hello {
init() {
print("Hello 생성")
}
}
struct Hello2 {
init() {
print("Hello2 생성")
}
}
struct Hi {
var name: String
//lazy
//lazy 키워드를 사용하면 인스턴스 생성이 바로 되지 않는다.
lazy var hello = Hello()
//lazy 키워드가 없을 때는 Hi가 생성될 때 Hello2도 같이 인스턴스 생성이 된다.
var hello2 = Hello2()
init(_ name: String) {
self.name = name
print("HI 생성\(name)")
}
}
var hi = Hi("")
//Hello2 생성
//Hi 생성
//lazy 키워드는 나중에 직접 생성 해줘야 한다.
hi.hello
//Hello 생성
lazy 키워드가 없을 때는 Hi struct가 생성될 때, Hello2도 함께 생성되는 것을 볼 수 있다
Hi struct만 생성한 시점에서는 lazy 키워드에 있는 값은 생성되지 않았다.
hi.hello를 직접 생성한 순간 lazy 키워드가 메모리에 올라가서 프린트가 찍히는 것을 볼 수 있다.
1. lazy는 반드시 var(변수)와 함께 사용해야 한다.
위에서 말한 것과 같이 lazy 변수는 초기값이 나중에 생기기 때문에 let으로 선언이 불가능하다.
2. struct, class 에서만 사용이 가능하다.
3. Computed Property에 사용될 수 없다.
lazy는 처음 사용될 때 메모리에 값을 올리고 그 이후에 계속 메모리에 올라온 값을 사용한다.
때문에 값을 연산하는 computed property에는 사용할 수 없다.
4. lazy에 특별한 연산을 통해 값을 넣어주기 위해서는 클로저를 사용한다.
기본적으로 일반 변수는 클래스가 생성된 이후에 접근이 가능하기 때문에 클래스내의 다른 메소드나 프로퍼티에는 self를 통해 접근이 불 가능하다.
하지만 lazy를 이용하면 생성 후 추후 접근이라는 의미이기 때문에 클로저 내에서 self로 접근이 가능하다.
class Person {
var name: String
lazy var greeting: String = {
return "Hello my name is \(self.name)"
}()
init(name: String) {
self.name = name
}
}
var me = Person(name: "Ann")
print(me.greeting)
me.name = "Chris"
print(me.name)
print(me.greeting)
//Hello my name is Ann
//Chris
//Hello my name is Ann
다음 코드를 보면 ()초기화를 통해 즉시 실행한 후 결과를 돌려주고 끝나버리기 때문에 메모리 누수의 걱정이 없다.
만약 값을 바꿔주고 싶다면 타입을 string이 아닌 클로저 자체로 만들어주면 가능하다.
class Person2 {
var name: String
lazy var greeting: () -> String = { [weak self] in
return "Hello my name is \(self?.name ?? "")"
}
init(name: String) {
self.name = name
}
}
var me2 = Person2(name: "apple")
print(me2.greeting())
me2.name = "banana"
print(me2.greeting())
//Hello my name is apple
//Hello my name is banana
클로저 자체를 담고 있는 변수라면 [weak self]를 통해 메모리 누수 방지를 해줘야 한다.
클로저 자체가 메모리에 올라가 있고 self는 내부에서 클로저를 참고하고 있기 때문에 결과값이 바뀌게 된다.
'Dev > SWIFT' 카테고리의 다른 글
[Swift] replacingOccurrences(of:with:) (0) | 2024.01.30 |
---|---|
[Swift-UI] 화면전환하기 (0) | 2024.01.11 |
[Swift] Decodabe, Encodable, Codable (0) | 2024.01.09 |
[Swift] URLSession (1) | 2024.01.07 |
[Swift] URL 구성요소 (1) | 2024.01.04 |