본 게시물은 Hacking with swift , 군옥수수님의 게시글을 참고하여 작성되었습니다.
Lazy properties
Swift에서 메모리는 굉장히 예민한 주제인 것을 알 수 있습니다. 그런 예민함이 보다 메모리를 효율적으로 관리할 수 있는 방향으로 이어졌습니다. 이번에는 메모리와 관련된 문법 중 하나인lazy
에 대해 알아보도록 하겠습니다.
애플 공식 문서
"A lazy stored property is a property whose initial value is not calculated until the first time it is used"
"lazy변수는 처음 사용되기 전까지는 연산이 되지 않는다."
인스타그램을 예로 들어보자면, 인스타그램을 실행시키면 가장 상단에 본인의 팔로워들의 아이콘들이 존재하고 이 아이콘을 클릭하면 해당 유저가 올린 스토리 영상을 확인할 수 있습니다.
인스타그램을 실행시켰을 때 이러한 영상들도 모두 서버로부터 가져오는 작업을 할까요?
만일 여러분이 애플리케이션을 실행하는 동안 한 번도 스토리들을 클릭하여 확인하지 않는다면 이는 쓸데없이 메모리만 차지하고 애플리케이션을 실행할 때 딜레이도 존재할 수 있습니다.
해당 영상들은 여러분이 클릭했을 때만 보여주기만 하면 되기 때문입니다.
즉, 처음 사용되기 전까지는 로드되지 않다가 영상을 보려고 클릭하면 해당 영상들이 서버로부터 로드되는 것입니다.
Lazy 프로퍼티는 언제 사용하고 장점은?
Swift의 lazy 프로퍼티
는 실제로 사용될 때까지 프로퍼티 생성을 지연시킬 수 있습니다. 이는 속성들을 연산 프로퍼티 처럼 만듭니다.
그러나 연산 프로퍼티와 는 달리 계산된 결과를 저장하므로 속성에 대한 후속 액세스가 작업을 다시 실행하지 않습니다. 이를 통해 사용하지 않을 때 추가 성능을 제공할 수 있습니다(코드가 실행되지 않기 때문). 또한 반복적으로 사용할 경우 성능이 향상됩니다.(값이 캐시 되기 때문)
하지만, 그렇다고해서 모든 곳에 lazy 프로퍼티
를 사용해야 한다는것은 아닙니다. lazy 프로퍼티
보다 연산 프로퍼티를 선호하는 경우는 다음과 같습니다.
- lazy 프로퍼티를 사용하면 예상치 못한 작업이 실수로 생성될 수 있습니다. 예를 들어 게임을 빌드하고 복잡한 lazy 프로퍼티에 처음으로 액세스하면 게임 속도가 느려질 수 있으므로 미리 느린 작업을 수행하고 방해가 되지 않도록 하는 것이 훨씬 좋습니다.
- lazy 프로퍼티는 항상 결과를 저장합니다. 이 결과는 불필요하거나(다시 사용하지 않기 때문에) 무의미 할 수 있습니다.(자주 다시 계산해야 하므로)
- lazy 프로퍼티는 연결된 기본 개체를 변경하므로 let 구조에서는 사용할 수 없습니다.
코드를 최적화하려고 할 때 , 일반적으로 lazy 프로퍼티와 같은 것을 조기에 분산시키는 것보다 최적화해야하는 문제가 실제로 발생할 때까지 기다리는 것이 좋습니다.
Lazy를 사용하기 위한 조건
1. lazy는 반드시 변수와 함께 쓰여야 한다.
lazy
는 반드시var
와 사용되어야 합니다.
이는 한 번만 생각해보시면 쉽게 이해하실 수 있습니다. 기본적으로 lazy
로 선언된 변수는 초기에는 값이 존재하지 않고 이후에 값이 생기는 것이기 때문에let
으로는 선언될 수 없습니다.
2. struct, class
기본적으로lazy
는struct
와class
에서만 사용할 수 있습니다
3. lazy vs 연산 프로퍼티
연산 프로퍼티에는lazy
키워드를 사용할 수 없습니다.
lazy
는 처음 사용될 때 메모리에 값을 올리고 그 이후부터는 계속해서 메모리에 올라온 값을 사용합니다. 사용할 때마다 값을 연산하여 사용하는Computed 프로퍼티
에는 사용할 수 없습니다.
4. lazy and closure
lazy
에 어떤 특별한 연산을 통해 값을 넣어주기 위해서는 코드 실행 블록인 클로저
를 사용합니다.
class
나 struct
의 다른 프로퍼티의 값을 lazy
변수에서 사용하기 위해서는 closure
내에서 self
를 통해 접근이 가능합니다.
기본적으로 일반 변수들은 클래스가 생성된 이후에 접근이 가능하기 때문에 클래스 내의 다른 영역(메서드, 일반 프로퍼티)에서는 self
를 통해 접근할 수 없지만 lazy
키워드가 붙으면 생성 후 추후에 접근할 것이라는 의미이기 때문에 closure
내에서 self
로 접근이 가능합니다.
예를 들어 FamilyTree
라는 구조체를 만들어 보겠습니다. 누군가를 위한 족보를 만드는 것은 많은 시간이 걸립니다. 그렇죠?
struct FamilyTree {
init() {
print("족보를 만듭니다.")
}
}
다음 FamilyTree
를 구조체 Person
의 내부 프로퍼티로 만들 수 있습니다.
struct Person {
var name: String
var familyTree = FamilyTree()
init(name: String) {
self.name = name
}
}
var ed = Person(name: "서근")
하지만 우리가 만약 누군가를 위한 족보가 항상 필요하지 않고 처음에만 액세스 하는 혹은 클릭했을때만 엑세스 되는 것이 필요하다고 하면 lazy
키워드를 사용할 수 있습니다. 그러면 많은 메모리를 사용하지 않겠죠?
lazy var familyTree = FamilyTree()
이제 "족보를 만듭니다."라는 메시지를 호출하고 싶다면 프로퍼티에 한번 이상 액세스 해야 합니다.
ed.familyTree
lazy 프로퍼티 TEST : 문제를 풀려면 이곳을 클릭해주세요.
읽어주셔서 감사합니다🤟
'SWIFT > Grammar' 카테고리의 다른 글
Swift : 기초문법 [프로퍼티 #4-1 Static] (0) | 2021.03.01 |
---|---|
Swift : 기초문법 [기본 연산자] (0) | 2021.03.01 |
Swift : 기초문법 [Array의 프로퍼티 및 메서드] (3) | 2021.02.28 |
Swift : 기초문법 [String의 프로퍼티 및 메서드] (0) | 2021.02.27 |
Swift : 기초문법 [구조체 - Struct] (0) | 2021.02.26 |