Weekoding

[Swift] Property Observer 본문

공부 노트(Swift)

[Swift] Property Observer

Weekoding 2023. 1. 1. 22:41

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를 모두 구현하면,

변수의 값이 변경될 때 다음의 순서로 호출됨을 한번 더 인지하고 넘어가자.

  1. willSet 호출
  2. 저장 프로퍼티 값 변경
  3. 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

https://zeddios.tistory.com/247

Comments