[Swift] Lazy Stored Property (지연 저장 속성)

어흥·2024년 5월 12일

Swift

목록 보기
10/28

안녕하세요! 오늘은 지연 저장 속성에 대해서 알아보겠습니다.
지연 저장 속성에 대해서 알아보기 전에, 저장 속성에 대해서 알아보겠습니다.

저장 속성

저장 속성은 값이 저장되는 속성을 말합니다.

struct FixedLengthRange {
    var firstValue: Int
    let length: Int
}
var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
rangeOfThreeItems.firstValue = 6

위 코드에서 firstValue, length은 저장 속성에 해당됩니다.

저장 속성 특성

  • 각 속성 자체가 고유의 메모리 공간을 갖습니다.
  • 선언할 때 값을 정하거나 생성자를 통해서 초기화해야합니다.

중요한 점은 저장 속성은 고유의 메모리 공간을 갖으며 그 공간 안에 값이 들어가 있어야 한다는 것입니다.

그럼 lazy stored property는 어떤 점이 다를까요?

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. (공식문서)

지연 저장 속성은 해당 속성에 접근하기 전까지 해당 속성의 값이 계산되고 초기화되지 않는 속성을 말합니다.

즉 저장 속성의 특징인 '초기화'를 지연하는 것입니다. 일반적으로 많은 메모리 공간을 가지는 이미지 뷰 등과 같이 반드시 처음부터 초기화가 필요하지 않은 경우 사용하기 적합합니다.

특징

  • 해당 속성에 대한 접근을 해야 초기화됩니다. (메모리 공간 생성)
    값을 넣거나, 함수호출 코드, 계산코드, 클로저 코드 등도 모두 가능
  • lazy var로만 선언 가능합니다. (lazy let ❌)
  • 생성자에서 초기화하지 않기 때문에 반드시 기본값이 필요합니다.
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에 접근한다면 초기화가 한번만 진행된다는 보장이 없다는 것입니다.

동시성 문제가 발생하는 것입니다! 따라서 자주 사용하는 컴포넌트에 대해서 멀티쓰레드를 통해 동시에 접근하여 초기화되는 것을 조심할 필요가 있습니다.

0개의 댓글