공부 연습장 :-)

프로퍼티

|

프로퍼티

프로퍼티의 분류

  • 역할에 따른 분류 : 저장프로퍼티 / 연산프로퍼티
  • 소속에 따른 분류 : 인스턴스프로퍼티(일반적으로 인스턴스에 소속되는 프로퍼티) / 타입프로퍼티 (예외적으로 클래스와 구조체 자체에 소속되어 값을 가지는 프로퍼티)

저장 프로퍼티

  • 입력된 값을 저장하거나 저장된 값을 제공하는 역할
  • 상수 및 변수를 사용해서 정의가능
  • 클래스와 구조체에서는 사용이 가능하지만, 열거형에서는 사용할 수 없음

클래스 내에서 선언된 변수나 상수를 부름. 선언시 초기값을 할당해주어야함. (초기값을 할당하지 않으러면 반드시 옵셔널 타입으로 선언해주어야 함 - ? 혹은 ! 옵셔널타입으로)

cf. 하지만 구조체는 이같은 초기값으로부터 자유롭다. (초기화나 옵셔널로 지정해주지 않아도 문제가 없음.) 이는 멤버와이즈 초기화 구문이 제공되기 때문임 (멤버와이즈 초기화 구문 - 인스턴스 생성 시 인자값을 받아 프로퍼티의 값을 초기화시켜주는 역할을 함)

연산 프로퍼티

  • 특정 연산을 통해 값을 만들어 제공하는 역할
  • 변수만 사용해서 정의 가능
  • 클래스, 구조체, 열거형 모두에서 사용 가능

연산 프로퍼티는 다른 프로퍼티의 값을 연산처리하여 간접적으로 값을 제공. 이때 프로퍼티의 값을 참조하기 위해 내부적으로 사용하는 구문이 get 구문임. 함수와 비슷하게 return 키워드를 사용해서 값을 반환하고, 여기서의 return값이 프로퍼티가 제공하는 값이 됨.

get 구문을 통해서 연산 프로퍼티가 값을 반환하는 기능을 한다.

class/struct/enum 객체명 {
  ...
  var 프로퍼티명: 타입 {
    get {
      필요한 연산 과정
      return 반환값
    }
    set(매개변수명) {
      필요한 연산구문
    }
  }
}
struct UserInfo {
    //저장 프로퍼티 : 태어난 연도
    var birth : Int!
    
    //연산 프로퍼티 : 올해가 몇년도인지 계산
    var thisYear : Int! {
        get {
            let dateFormat = DateFormatter()
            dateFormat.dateFormat = "yyyy"
            return Int(dateFormat.string(from: <#T##Date#>))
        }
    }
    
    //연산 프로퍼티 : 올해 - 태어난 연도 + 1
    var age : Int {
        get {
            return (self.thisYear - self.birth) + 1
        }
    }
}

let info = UserInfo(birth: 1980)
print(info.age)

지연 저장형 프로퍼티 lazy

저장형 프로퍼티의 값이 곧바로 지정될 수 없을때 사용한다. 꼬는 인스턴스가 만들어져야 알 수 있는 타입의 외적 요소에 프로퍼티가 의존하는 경우도 있다. 이런 환경을 가리켜 지연 로딩이라고 부른다. 지연로딩의 관점은 프로퍼티의 값이 필요할 때 계산한다는 의미이고, 이 지연으로 인해 프로퍼티의 값을 계산하는 일도 인스턴스 초기화 이후로 미뤄진다.

struct Town {
    let region = "South" //let - 저장용 프로퍼티, 읽기전용
    var population = 5_422
    var numberOfStopLights = 4
    
    enum Size {
        case small
        case medium
        case large    }

    /*
     지연 저장형 프로퍼티 - 프로퍼티의 값이 필요해야 계산한다.
     이 지연으로 인해 프로터피의 값을 계산하는 일도 인스턴스 초기화 이후로 이뤄진다.
     따라서 그 값이 나중에 변경되므로 지연 프로퍼티는 var로 선언해야한다.
     */
    
    lazy var townSize: Size = {
        switch self.population{
        case 0...10_000:
            return Size.small
        case 10_001...100_000:
            return Size.medium
        default:
            return Size.large
        }
    }()

  • townSize 프로퍼티의 타입은 Size로 선언했다. 예를들어 myTown.townSize = Size.small과같은 식으로 코드를 작성하지 않았기 때문에 이 프로퍼티의 값은 지금 바로 설정한 것이 아니다.

Comments