swift 기본문법 - 프로퍼티(property)와 프로퍼티 감시자(property observer)

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
인프런, 야곰의 스위프트 기본문법 강좌를 듣고 정리하였습니다.


프로퍼티(property)

  • 저장 프로퍼티(stored property)
  • 연산 프로퍼티(computed property)
  • 인스턴스 프로퍼티(instance property)
  • 타입 프로퍼티(type property)

프로퍼티는 구조체, 클래스, 열거형 내부에 구현함으로써 타입과 연관된 값들을 표현할 떄 사용한다.

struct Student {

  // 인스턴스 저장 프로퍼티
  var name: String = ""
  var `class`: String = "Swift"
  var koreanAge: Int = 0

  // 인스턴스 연산 프로퍼티
  var westernAge: Int {

    // westernAge 값을 꺼내가려 한다면 koreanAge의 값을 역으로 환산하여 가져간다.
    get {
      return koreanAge -1
    }

    // westernAge라는 프로퍼티에 값을 셋팅하면 직접 값을 저장하는게 아니라
    // koreanAge의 프로퍼티의 값들을 연산하여 할당하거나 변환해준다.
    set(inputValue) {
      koreanAge = inputValue + 1
    }
  }

  // 타입 저장 프로퍼티: 타입과 연관되어 저장이 될 프로퍼티
  static var typeDescription: String = "학생"

  // 읽기 전용 인스턴스 연산 프로퍼티(get만 구현되어있을때)
  var selfIntroduction: String {
    get {
      return "저는 \(self.class)\(name)입니다."
    }
  }
  // 타입 메서드
  static var selfIntroduction: String {
    return "학생 타입입니다"
  }
}

// 타입 연산 프로퍼티 사용
print(Student.selfIntroduction)  // 학생 타입입니다

// 인스턴스 생성
var zehye: Student = Student()
zehye.koreanAge = 10

// 인스턴스 저장 프로퍼티 사용
zehye.name = "zehye"
print(zehye.name)  // zehye

// 인스턴스 연산 프로퍼티 사용
print(zehye.selfIntroduction)  // 저는 Swift반 zehye입니다.
print("제 한국나이는 \(zehye.koreanAge)살이고, 미쿸 나이는 \(zehye.westernAge)살 입니다.")

응용

struct Money {
    var currentcyRate: Double = 1100
    var dollar: Double = 0
    var won: Double {
        get {
            return dollar * currentcyRate
        }
        set {
            dollar = newValue / currentcyRate
        }
    }
}

var moneyInMyPocket = Money()

moneyInMyPocket.won = 110000
print(moneyInMyPocket.won)  // 110000.0
moneyInMyPocket.dollar = 10
print(moneyInMyPocket.won)  // 11000.0

저장 프로퍼티와 연산 프로퍼티의 기능은 함수, 메서드, 클로저, 타입 등의 외부에 위치한 지역/전역 변수에도 모두 사용가능하다.

var a: Int = 100
var b: Int = 200
var sum: Int {
  return a + b
}

print(sum)  // 300

프로퍼티 감시자(property observer)

프로퍼티 감시자를 사용하면 프로퍼티 값이 변경될 때 원하는 동작을 수행할 수 있다.

struct Money {
  var currentcyRate: Double = 1100 {
    willSet(newRate) {  
      print("환율이 \(currentcyRate)에서 \(newRate)으로 변경될 예정입니다")
    }
    didSet(oldRate) {
      print("환율이 \(oldRate)에서 \(currentcyRate)으로 변경되었습니다")
    }
  }
}

즉, currentcyRate 값이 변경될 때 willSet, didSet이 동작하게 된다.

  • willSet: currentcyRate가 바뀌기 직전에 동작
    • newRate: 바뀔 값이 들어옴
  • didSet: currentcyRate가 바뀌고 난 후 동작
    • oldRate: 바뀌기 이전의 값이 들어옴
var dollar: Double = 0 {
  willSet {  // willSet의 암시적 매개변수 이름 newValue
    print("\(dollar)달러에서 \(newValue)달러로 변경될 예정입니다")
  }
  didSet {  // didSet의 암시적 매겨변수 이름 oldValue
    print("환율이 \(oldValue)달러에서 \(dollar)달러로 변경되었습니다")
  }
}

연산 프로퍼티에서의 사용

프로퍼티 감시자와 연산 프로퍼티 기능을 동시에 사용은 불가능하다 > willSet, didSet은 저장되는 값이 변경될 때 호출되기 때문

var won: Double {
  get {
    return dollar * currentcyRate
  }
  set {
    dollar = newValue / currentcyRate
  }
}

프로퍼티 감시자의 사용

var moneyInMyPocket: Money = Money()

// 환율이 1100.0에서 1150.0으로 변경될 예정입니다
moneyInMyPocket.currentcyRate = 1150
// 환율이 1100.0에서 1150.0으로 변경되었습니다

// 0.0달러에서 10.0달러로 변경될 예정입니다
moneyInMyPocket.dollar = 10
// 0.0달러에서 10.0달러로 변경되었습니다

print(moneyInMyPocket.won)  // 11500.0

프로퍼티 감시자의 기능은 함수, 메서드, 클로저, 타입 등의 외부에 위치한 지역/전역 변수에도 모두 사용가능하다.

var a: Int = 100 {
  willSet {
    print("\(a)에서 \(newValue)로 변경될 예정입니다"
  }
  didSet {
    print("\(oldValue)에서 \(a)로 변경되었습니다")
  }
}

// 100에서 200으로 변경될 예정입니다
a = 200
// 100에서 200으로 변경되었습니다