본문 바로가기

Swift

[Swift] Computed Property 는 언제 쓰는지 알아보자

Computed Property를 직역하면 계산된 속성이 됩니다. 하지만 수학적 계산이 실행된다는 의미는 아닙니다. 다른 속성을 기반으로 해당 속성 값이 결정된다는 의미입니다.

 

저장 속성(Stored Property)은 값을 저장할 메모리 공간을 가지고 있습니다. 반면에, 연산 프로퍼티(Computed Property)는 메모리 공간을 가지지 않습니다. 다른 속성에 저장된 값을 읽어서 필요한 계산을 실행한 다음 반환(return)하는 것입니다. 또한 연산 프로퍼티에 값을 할당하는 것은 속성으로 전달된 값을 다른 속성에 저장하는 것입니다.

 

이런 특징 때문에 속성에 접근할 때마다 다른 값이 반환될 수 있습니다. 그러므로 연산 프로퍼티는 let이 아닌 var로 선언해야합니다. 저장 속성은 클래스, 구조체에만 추가할 수 있지만 연산 프로퍼티는 클래스, 구조체 뿐만아니라 열거형에도 추가할 수 있습니다.

 

이제 문법을 살펴보도록 하겠습니다.

 

var name: Type {
    get {
        // statements
        return value
    }
    
    set(name) {
        // statements
    }
}

 

연산 프로퍼티는 선언 시점에 기본값을 저장하지 않습니다. 따라서 형식 추론이 불가능하므로 반드시 자료형(Type)을 같이 선언해주어야 합니다. getter 에는 꼭 return 값을 명시해주어야 합니다. setter 는 값을 저장할 때 실행됩니다. 괄호와 파라미터는 생략이 가능하며 파라미터 값은 newValue 키워드로 접근이 가능합니다.

 

연산 프로퍼티를 활용하여 나이를 계산하는 예제를 살펴보겠습니다.

 

class Person {
    var name: String
    var yearOfBirth: Int

    init(name: String, year: Int) {
        self.name = name
        self.yearOfBirth = year
    }

    var age: Int {
        get {
            let calendar = Calendar.current
            let now = Date()
            let year = calendar.component(.year, from: now)
            return year - yearOfBirth
        }
        
        set {
            let calendar = Calendar.current
            let now = Date()
            let year = calendar.component(.year, from: now)
            yearOfBirth = year - newValue
        }
    }
}

 

태어난 년도(yearOfBirth)를 가지고 나이(age)를 계산하는 속성을 선언하였습니다.

 

let person = Person(name: "Yeom", year: 2002)
print(person.age)
// Prints "17"

person.age = 50
print(person.yearOfBirth)
// Prints "1969"

 

항상 setter 를 선언해주어야 할까요? 아닙니다.

읽기 전용 연산 속성(Read-only Computed Properties)도 존재하고 많이 쓰입니다. 하지만 쓰기 전용은 없습니다.

 

var name: Type {
    get {
        // statements
        return value
    }
}

 

get 키워드는 생략이 가능합니다. 그렇기 때문에 주로 아래 예시의 방식으로 많이 사용합니다. 할당 연산자(=)가 없음에 주의하세요! 할당 연산자를 넣게 되면 클로저를 변수에 할당한다는 의미가 되기 때문입니다.

 

var name: Type {
    // statements
    return value
}

정리

  • 저장하는 메모리 공간을 가지지 않는 연산 속성에 대해서 알아보았습니다.
  • 저장 속성과의 차이점을 알아보았습니다.
  • setter 를 생략한 읽기 전용 연산 속성도 알아보았습니다.