안녕하세요! 오늘은 지연 저장 속성에 대해서 알아보겠습니다.
지연 저장 속성에 대해서 알아보기 전에, 저장 속성에 대해서 알아보겠습니다.
저장 속성은 값이 저장되는 속성을 말합니다.
struct FixedLengthRange {
var firstValue: Int
let length: Int
}
var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
rangeOfThreeItems.firstValue = 6
위 코드에서 firstValue, length은 저장 속성에 해당됩니다.
중요한 점은 저장 속성은 고유의 메모리 공간을 갖으며 그 공간 안에 값이 들어가 있어야 한다는 것입니다.
그럼 lazy stored property는 어떤 점이 다를까요?

A lazy stored property is a property whose initial value isn’t calculated until the first time it’s used. You indicate a lazy stored property by writing the lazy modifier before its declaration. (공식문서)
지연 저장 속성은 해당 속성에 접근하기 전까지 해당 속성의 값이 계산되고 초기화되지 않는 속성을 말합니다.
즉 저장 속성의 특징인 '초기화'를 지연하는 것입니다. 일반적으로 많은 메모리 공간을 가지는 이미지 뷰 등과 같이 반드시 처음부터 초기화가 필요하지 않은 경우 사용하기 적합합니다.
class DataImporter {
var filename = "data.txt"
}
class DataManager {
lazy var importer = DataImporter()
var data: [String] = []
}
let manager = DataManager()
manager.data.append("Some data")
manager.data.append("Some more data")
lazy 저장 속성은 속성 앞에 'lazy'를 추가하면 됩니다. (let은 절대 안됨)
그렇다면 lazy 저장 속성은 왜 사용할까요?
1. 메모리 공간 낭비를 막을 수 있습니다. -> 속성에 접근하기 전까지 초기화를 하지 않기 때문
2. 값을 초기화할 때, 다른 속성들을 이용해야 할 때 사용하기 적합합니다.
공식 문서를 보면 lazy stored property에 대해 주의할 점이 나와 있습니다.
If a property marked with the lazy modifier is accessed by multiple threads simultaneously and the property hasn’t yet been initialized, there’s no guarantee that the property will be initialized only once.
lazy stored property는 해당 속성에 접근할 때 초기화된다는 특징을 가지고 있다는 점 이제 알고 계시죠! 문제는 여러 쓰레드가 동시에 초기화되지 않은 lazy stored property에 접근한다면 초기화가 한번만 진행된다는 보장이 없다는 것입니다.
동시성 문제가 발생하는 것입니다! 따라서 자주 사용하는 컴포넌트에 대해서 멀티쓰레드를 통해 동시에 접근하여 초기화되는 것을 조심할 필요가 있습니다.