오늘은 프로퍼티 감시자를 공부했다.
프로퍼티 감시자(Property Observers)는 프로퍼티 값이 변경될 때 원하는 동작을 수행 하게 할 수 있는 기능이다.
struct Money {
// 프로퍼티 감시자 사용
// 저장 프로퍼티이다. 뒤에다가 블럭을 만든다.
var currencyRate : Double = 1100 {
// 바뀌기 직전에 호출
willSet(newRate) {
print("환율이 \(currencyRate)에서 \(newRate)으로 변경될 예정입니다.")
}
// 바뀌었다. 에 호출
didSet(oldRate) {
print("환율이 \(oldRate)에서 \(currencyRate)으로 변경 되었습니다.")
}
}
}
프로퍼티 감시자는 저장 프로퍼티 뒤에 블럭을 만들어 사용 할 수 있다. 그리고 willSet 과 didSet 이 있는데, 각자 용도에 따라 다르다.
willSet은 프로퍼티의 값이 바뀌기 직전에 호출하는 블럭이다. 따라서 수가 바뀌기 전에 출력이 된다.
didSet은 프로퍼티의 값이 바뀌고 난 뒤에 호출하는 블럭이다. 따라서 수가 바뀌고 난 뒤에 출력이 된다.
프로퍼티 감시자의 암시적 매개변수 이름 사용
struct Money {
// 프로퍼티 감시자 사용
var dollar: Double = 0 {
//willSet의 암시적 매개변수 이름 newValue
willSet {
print("\(dollar)에서 \(newValue)달러로 변경될 예정입니다.")
}
// didSet의 암시적 매개변수 이름 oldValue
didSet {
print("\(oldValue)에서 \(currencyRate)달러로 변경될 예정입니다.")
}
}
}
위 코드를 보면 각 블럭에 해당하는 이름이 없다. 그렇지만 컴파일러는 암시적으로 각각 매개변수의 이름을 정해줘 사용할 수 있게 해준다.
willSet의 경우에는 newValue라는 이름으로 사용이 가능하다. didSet의 경우에는 oldValue 라는 이름으로 사용이 가능하다.
연산 프로퍼티에서의 프로퍼티 감시자
struct Money {
var won: Double {
get {
return dollar * currencyRate
}
set {
dollar = newValue / currencyRate
}
/* 프로퍼티 감시자와 연산 프로퍼티 기능을 동시에 사용할 수 없습니다. */
// willSet, didSet은 저장되는 값이 변경될때 사용하는건데 연산 프로퍼티에 있으면
// 이미 변경되는걸 굳이 부르지 않는건가? 잘 모르겠다.
/*willSet {
}
*/
}
}
연산 프로퍼티를 사용할 경우에는 예전에 공부했던 get set 말고는 willSet과 didSet을 사용할 수 없다. 이유는..이미 연산을 하는 프로퍼티인데 굳이 필요할까? 라는 걸 컴파일러가 알아서 생각하나보다..사실 잘 모르겠다.. 더 공부하겠다!
사용
var moneyInMyPocket: Money = Money()
// 환율이 1100.0 에서 1150.0 으로 변경될 예정입니다.
moneyInMyPocket.currencyRate = 1150
// 환율이 1100.0 에서 1150.0 으로 변경 되었습니다.
// 달러가 0 에서 10.0 으로 변경될 예정입니다.
moneyInMyPocket.dollar = 10
// 달러가 0 에서 10.0 으로 변경 되었습니다.
print(moneyInMyPocket.won)
실제로 프로퍼티 감시자를 사용해보겠다.
인스턴스를 만들어 직접 임의로 값을 변경하면 주석으로 처리된 문구들이 실제로 나온다.
이렇게 바뀌기 직전과, 바뀌고 난뒤에를 확인할 수 있는 프로퍼티 감시자이다.
이외의 사용
var a: Int = 100 {
willSet {
print("\(a)에서 \(newValue)으로 변경될 예정입니다.")
}
didSet {
print("\(oldValue)에서 \(a)으로 변경되었습니다.")
}
}
// 100 에서 200으로 변경될 예정입니다.
a = 200
// 100 에서 200으로 변경되었습니다.
이외에 함수, 메서드, 클로저, 타입 등의 외부에 위치한 지역/전역 변수에도 모두 사용이 가능하다.
이 코드에는 전역 변수에 프로퍼티 감시자를 적용한 모습이다.
따라서 마지막 줄에 변경하는게 보이는데, 실제 돌려보면 위아래 주석 처럼 출력이 된다.
댓글