우리는 종종 변수 앞에 lazy가 붙는 경우를 볼 수 있다.
나 또한 lazy 변수를 몇번 마주쳤지만, 다른 부분에 정신없는 와중이어서 대충 "메모리를 필요할 때만 쓰게 해주는 역할이다" 정도로만 이해하고 지났쳤지만, 이번에 Core Data를 공부하던 중, lazy var persistContainer 라는 변수를 보고, lazy가 무엇인지 공부를 시작했다.
애플 공식 문서에서 lazy 는 다음과 같이 설명되어 있는데
Apple Developer Documentation
developer.apple.com
A sequence containing the same elements as this sequence, but on which some operations, such as map and filter, are implemented lazily.
Declaration - var lazy: LazySequence<String> { get }
"이 시퀀스와 동일한 요소를 포함하지만 map 및 filter와 같은 일부 연산이 느리게 구현되는 시퀀스입니다."
라고 해석할 수 있다.
느리게 구현된다? 그냥 천천히 구현된다는 건가? 아니면 어떤 조건을 가지고 조건에 맞을 때만 구현된다는 건가?
개발자 문서인데 이렇게 불친절한 건 오랜만에 보는 것 같다.
여기서 이야기하는 map은 지도를 의미하는 것이 아니라, swift map(_:) 함수이다.
map과 filter 함수는 모두 고차 함수로서, map은 데이터를 변형하기 위한 함수이고, filter는 데이터를 추출하기 위한 함수이다.
설명이 너무 모호해서 좀 더 구글링을 해보니까 예전에 작성된 글에는 개발자 문서가 다음과 같이 인용되어 있다.
"lazy 저장 변수는 이것이 처음 사용되기 전까지 초기값이 계산되지 않는 프로퍼티 입니다. 사용자는 선언부에 lazy 수정자를 붙임으로써 lazy 저장 변수를 나타낼 수 있습니다."
일단 여기서는 확실하게 조건부로 초기값이 계산된다고 나와있는 것 같다.
검증하기 위해 Apple Developer를 계속 뒤져봤지만, 아무리 찾아봐도 저런 설명은 찾을 수가 없었다.
아마도 원래 저 설명이었는데 2021년 중에 설명이 바뀐 것 같다.
바뀐 점은 다음과 같다.
대상 : 프로퍼티 -> 시퀀스 ( 모호해짐)
대상 : 모든 프로퍼티의 초기화 -> 일부 연산 (메모리 -> cpu연산)
기존에는 모든 변수가 lazy가 붙으면 초기화가 사용하기 전까지 되지 않는다에서
변경된 부분은 map이나 filter와 같은 일부 연산(고차함수들)이 느리게 구현된다로 바뀌었다.
lazy는 여전히 property가 run 타임에서 사용될 때 초기화가 되는 용도로 쓰일 것이다.
하지만, 이를 변수, 프로퍼티라고 이야기하지 않고 시퀀스라고 이야기하는 건 모든 상황에서 똑같은 메커니즘으로 작동하지 않기 때문이지 않을까 예상을 한다.
또한 기존에는 메모리의 효율을 높이기 위해서라고 알려져있었다면, 연산을 미룬다는 걸로 보아 CPU 연산을 효율적으로 하기 위한 부분이 중요해지지 않았나 싶다.
'iOS 개발 > Swift' 카테고리의 다른 글
[ARC] 성능을 위해 unowned를 꼭 써야할까? (0) | 2023.02.03 |
---|---|
[ARC] Lazy 변수 클로저에서 Unowned 캡처가 항상 안전할까? (0) | 2023.02.02 |
[Concurrency] Semaphore로 비동기적 이벤트를 동기적으로 발생시키기 (0) | 2023.01.20 |
[ARC] 약한참조(Weak, Unowned)에 대해서 (0) | 2022.11.06 |
[Swift] 지정한 For-Loop 탈출하기 (0) | 2022.10.03 |
[Swift] Stride 함수를 사용하자 (0) | 2022.10.02 |
[Swift] appDelegate 참조 안전하게 하기 (0) | 2021.11.10 |
[Swift] 프로토콜(Protocol)을 가장 기초부터 (2) | 2021.09.02 |