Weekoding
[Swift] Property Observer 본문
Property Observer가 궁금해서 Property까지 공부해 놓고
프로젝트 때문에 Observer에 대한 공부가 늦었다.
이것도 결국은 하나의 핑계니까 바로 시작해보자
📂 Property Observer
Property observers observe and respond to changes in a property’s value. Property observers are called every time a property’s value is set, even if the new value is the same as the property’s current value.
→ 프로퍼티의 값의 변화를 Observe하고, respond한다고 한다.
값이 set될 때마다 호출되며, 새로운 값이 현재 값과 같아도 호출된다고 한다.
You can add property observers in the following places:
• Stored properties that you define
• Stored properties that you inherit
• Computed properties that you inherit
→ Observer는 다음과 같은 상황에 추가될 수 있다.
- 정의된 저장 프로퍼티(lazy 제외)
- 상속된 저장 프로퍼티
- 상속된 계산 프로퍼티
부모 클래스로부터 상속된 프로퍼티는 저장/계산 프로퍼티 모두 Observer를 추가할 수 있지만,
그렇지 않은 경우에는 저장 프로퍼티만 Observer를 추가할 수 있다.
⌘ '정의된 계산 프로퍼티' 는 관찰자를 추가하지 않고, 속성의 setter를 이용하여 값 변경을 관찰하고 응답할 수 있다고 한다.
(조금 더 읽어볼까?)
You have the option to define either or both of these observers on a property:
• willSet is called just before the value is stored.
• didSet is called immediately after the new value is stored.
→ 다음과 같은 Observer를 하나 혹은 모두 선택하여 추가할 수 있다.
willSet: 값이 저장되기 전에 호출
didSet: 값이 저장된 직후 호출
추가적으로 Observer를 구현할 때, 상수 파라미터가 전달된다. (활용하기 정말 좋을 것 같다)
didSet: 이전의 변수 값을 전달한다. 따로 설정하지 않는다면 기본 변수명은 oldValue.
willSet: 새로운 변수 값을 전달한다. 따로 설정하지 않는다면 기본 변수명은 newValue.
❌ 잘못된 코드
예제를 넣으려고 아주 간단한 코드를 생각해 봤는데, 바로 잘못된 점을 알아내어 기록한다.
문제점: bestScore에 저장되는 값이 변수의 본래 목적에 맞지 않다.
//bestScore: 새로운 최고기록을 저장하는 변수
//저장 프로퍼티에 Observer 추가
var bestScore: Int = 0 {
willSet(newRecord) {
print("I made a new Record: \(newRecord)")
}
didSet {
if bestScore > oldValue {
print("I tried, but need \(bestScore - oldValue)point more")
}
}
}
Observer를 사용할 때는, 코드블럭이 호출되는 시점이 상당히 중요하다.
didSet은 값이 저장된 직후 호출되기 때문에, if문을 타는 것이 중요한게 아니다.
예를 들어 bestScore = 5, 새로운 값 = 3인 상황에서
if문 내의 코드가 동작 되었어도 시점은 값이 이미 저장되고 난 직후이기 때문에 출력은 맞게 되었어도
bestScore에 값은 이미 Update가 되어버린 상황이 발생한다.
두 가지 Property Observer를 모두 구현하면,
변수의 값이 변경될 때 다음의 순서로 호출됨을 한번 더 인지하고 넘어가자.
- willSet 호출
- 저장 프로퍼티 값 변경
- didSet 호출
🗝 Maybe..
이 변수를 currentScore로 바꾸고, didSet에서 새 변수에 넣어주는 것은 어떨까 ?
var bestScore: Int = 0
var currentScore: Int = 0 {
willSet(newRecord) {
print("I made a new Record: \(newRecord)")
bestScore = newRecord
}
didSet {
//파라미터 oldValue를 현재 변수에 들어있는 값이라고 생각하면 편할 것 같다.
if bestScore > oldValue {
print("I tried, but need \(bestScore - oldValue)point more")
}
}
}
📌 마치며
변수가 변하는 시점을 캐치하고, 그에 맞는 조치를 취할 수 있는 Observer의 매력을 많이 느꼈고,
실제로도 아주 유용하게 사용했었다.
저장 프로퍼티를 사용할 때는 항상 세트로 활용하기 위해 애쓸 것 같은..ㅋㅋㅋ
오류 및 지적사항은 댓글로 남겨주시면 감사하겠습니다!
참고 :
https://docs.swift.org/swift-book/LanguageGuide/Properties.html
'공부 노트(Swift)' 카테고리의 다른 글
[Swift] CALayer - 둥근 모서리, 그림자, 그라데이션 (0) | 2023.02.05 |
---|---|
[Swift] UIView와 CALayer (0) | 2023.01.24 |
[Swift] Property(프로퍼티) (0) | 2022.10.03 |
[Swift] TextView PlaceHolder(Custom) (0) | 2022.08.08 |
[Swift] HTTP 접근 허용하기(App Transport Security) (0) | 2022.07.26 |