Swift
프로퍼티 감시자: Property Observers
소재훈
2022. 2. 6. 21:21
프로퍼티 감시자를 사용하면, 프로퍼티 값의 변경에 따라 원하는 작업을 수행할 수 있다.
프로퍼티 감시자는 프로퍼티의 값이 새로 할당될 때마다 호출되며, 변경전과 값이 같더라도 호출된다.
저장프로퍼티, 연산프로퍼티에 적용할 수 있다. 단, 상속받지 못한 연산프로퍼티에는 적용할 수 없다.
프로퍼티 감시자에는 두가지 종류가 있다.
1. willSet: 프로퍼티의 값이 변경되기 직전에 호출
2. didSet:프로퍼티의 값이 변경된 직후에 호출
willSet, didSet 메서드에는 매개변수가 하나씩 있다. willSet에는 변경될 값이고, didSet에는 변경되기 전의 값이다.
매개변수를 따로 지정해주지 않으면, willSet에는 newValue가 didSet에는 oldValue라는 매개변수 이름으로 자동지정된다.
class Account {
var credit: Int = 0 {
willSet {
print("잔액이 \(credit)원에서 \(newValue)원으로 변경될 예정입니다.")
}
didSet {
print("잔액이 \(oldValue)원에서 \(credit)원으로 변경되었습니다.")
}
}
}
let myAccount: Account = Account()
myAccount.credit = 1000
//잔액이 0원에서 1000원으로 변경될 예정입니다.
//잔액이 0원에서 1000원으로 변경되었습니다.
아래처럼 클래스를 상속받아, 기존의 연산프로퍼티를 재정의해서 프로퍼티 감시자를 구현할 수도 있다.
class Account {
var credit: Int = 0 {
willSet {
print("잔액이 \(credit)원에서 \(newValue)원으로 변경될 예정입니다.")
}
didSet {
print("잔액이 \(oldValue)원에서 \(credit)원으로 변경되었습니다.")
}
}
var dollarValue: Double {
get {
return Double(credit)
}
set {
credit = Int(newValue * 1000)
print("잔액을 \(newValue)달러로 변경 중입니다.")
}
}
}
class ForeignAccount: Account {
override var dollarValue: Double {
willSet {
print("잔액이 \(dollarValue) 달러에서 \(newValue)달러로 변경될 예정입니다.")
}
didSet {
print("잔액이 \(oldValue)달러에서 \(dollarValue)달러로 변경되었습니다.")
}
}
}
let myAccount: ForeignAccount = ForeignAccount()
myAccount.credit = 1000
myAccount.dollarValue = 2
//잔액이 0원에서 1000원으로 변경될 예정입니다.
//잔액이 0원에서 1000원으로 변경되었습니다.
//잔액이 1000.0 달러에서 2.0달러로 변경될 예정입니다.
//잔액이 1000원에서 2000원으로 변경될 예정입니다.
//잔액이 1000원에서 2000원으로 변경되었습니다.
//잔액을 2.0달러로 변경 중입니다.
//잔액이 1000.0달러에서 2000.0달러로 변경되었습니다.
프로퍼티 감시자가 있는 프로퍼티를 함수의 입출력 매개변수의 전달인자로 전달하면, 값이 변경되지 않아도 willSet, didSet감시자를 호출한다. 함수 내부에서 값이 변하던, 변하지 않던 간에 함수가 종료되는 시점에 값을 다시 쓰기 때문이다.