개발아 담하자

[Swift] Property Observer 의 didSet, willSet 사용하기 본문

📱 iOS

[Swift] Property Observer 의 didSet, willSet 사용하기

choidam 2020. 9. 25. 16:55

Property Observer

프로퍼티 옵저버는 프로퍼티의 값의 변화를 관찰하고, 이에 응답합니다.

새로운 값이 프로퍼티의 현재 값과 동일하더라도 속성의 값이 설정될 때마다(set) 호출됩니다.

 

프로퍼티 옵저버를 사용하기 위해서는 프로퍼티의 값이 반드시 초기화 되어 있어야 합니다.

또한 클래스의 init()안에서 값을 할당 할 때는 didSet, willSet은 호출 되지않습니다.

 

lazy 저장 프로퍼티를 제외하고, 정의된 저장 프로퍼티에 프로퍼티 옵저버를 추가할 수 있습니다. 

또한, 하위 클래스 내의 프로퍼티를 재정의하여, 상속된 프로퍼티에도 프로퍼티 옵저버를 추가할 수 있습니다.

 

즉, 원래는 저장 프로퍼티에만 프로퍼티 옵저버를 추가할 수 있지만, 부모 클래스를 상속하는 하위 클래스의 프로퍼티는 프로퍼티 옵저버를 추가할 수 있습니다.

 

 

정확한 내용은 공식 문서를 확인해주세요!

docs.swift.org/swift-book/LanguageGuide/Properties.html

 

Properties — The Swift Programming Language (Swift 5.3)

Properties Properties associate values with a particular class, structure, or enumeration. Stored properties store constant and variable values as part of an instance, whereas computed properties calculate (rather than store) a value. Computed properties a

docs.swift.org

didSet, willSet

스위프트는 프로퍼티 옵저버로 didSet, willSet 을 제공합니다.

하나의 프로퍼티에 대해 다음 옵저버를 정의할 수 있습니다.

 

willSet : 값이 저장되기 직전에 호출됩니다. 새로운 프로퍼티의 값이 newValue 로 제공됩니다.

didSet : 새로운 값이 저장된 직후에 호출됩니다. 이전 프로퍼티의 값이 oldValue 로 제공됩니다.

 

var myProperty: Int = 10{
   didSet(oldVal){
      //myProperty의 값이 변경된 직후에 호출, oldVal은 변경 전 myProperty의 값
   }
   willSet(newVal){
      //myProperty의 값이 변경되기 직전에 호출, newVal은 변경 될 새로운 값
   }
}

 

프로퍼티 옵저버의 가장 빈번한 사용은 Model에서 갱신된 값을 View에 보여줄 때 입니다.

View에 점수를 표시하는 Label이 있다고 가정하고, 점수가 바뀔때마다 View의 Label을 업데이트 한다고 가정합시다.

 

var score: Int = 0 {
   didSet {
      scoreLabel.text = "Score: \(score)"
   }
}

 

위 코드를 작성하면  score값이 바뀔 때마다 View의 값을 갱신하는 작업을 따로 해줄 필요가 없습니다.

 

var score: Int = 0 {
   didSet(oldVal) {
      print("현재 점수는: \(self.score), 이전 점수는: \(oldVal)")
   }
}

 

또는 위와 같이 현재 값과 바뀔 값을 비교하는 작업을 할 수도 있습니다.

 

 


class StepCounter {
    var totalSteps: Int = 0 {
        willSet(newTotalSteps) {
            print("About to set totalSteps to \(newTotalSteps)")
        }
        didSet {
            if totalSteps > oldValue  {
                print("Added \(totalSteps - oldValue) steps")
            }
        }
    }
}

totalStep 은 저장 프로퍼티 입니다.

위 예시는 totalStep 에 willSet, didSet 옵저버를 추가했습니다.

let stepCounter = StepCounter()
stepCounter.totalSteps = 200

totalStep 에 값을 추가했습니다.

About to set totalSteps to 200
Added 200 steps

값이 저장되기 직전인 willSet 이 먼저 호출된 후, 값이 저장된 직후에 didSet 이 호출됩니다.

 

stepCounter.totalSteps = 360

다시 totalStep 의 값을 360으로 바꾸면,

About to set totalSteps to 360
Added 160 steps

willSet 에서 새로운 값인 360이 출력되고,

didSet 에서 oldVal - newVal (360-200) 값인 160 이 출력됩니다.