大器晩成

속성감시자(프로퍼티 옵저버, Property Observer) 본문

iOS/Swift 문법

속성감시자(프로퍼티 옵저버, Property Observer)

zerobugpark 2024. 11. 25. 00:19

 

프로퍼티 옵저버(Property Observer)는 특정 프로퍼티를 계속 관찰하고 있다가 프로퍼티의 값이 변경되면 이를 알아차리고 반응합니다. 프로퍼티 옵저버는 우리가 프로터티의 값을 직접 변경하거나 시스템에 의해 자동으로 변경하는 경우에 상관없이 일단 프로퍼티의 값이 설정되면 무조건 호출합니다.

  • 클래스, 구조체, 열거형에서 동일하게 적용됩니다.

 

프로퍼티 옵저버 종류

  • willSet - 프로퍼티 값이 변경되기 직전에 호출되는 옵저버
  • didSet - 프로퍼티 값이 변경된 직후에 호출되는 옵저버

willSet

#1. willSet 옵저버의 정의 구문
var <프로퍼티명>: <타입> [=<초기값>] {
    wilSet [(<인자명>)] {
            <프로퍼티 값이 변경되기 전에 실행할 내용
    }
}
  • willSet 옵저버를 구현해 둔 프로퍼티에 값을 대입하면 그 값이 프로퍼티에 대입되기 직전에 willSet 옵저버가 실행됩니다.
  • 프로퍼티의 값이 변경되기 전에 처리해야 할 뭔가가 있다면 이 값을 이용하여 처리하면 됩니다. 단, 전달된 값은 참조할 수는 있지만 수정할 수는 없습니다.
  • 매개상수 형태로 전달되지만 시스템이 사용하는 기본 상수명인 newValue라는 이름으로 전달됩니다.
  • willSet:  예전값 - 프로퍼티 참조, 새로운 값 - newValue를 참조합니다

didSet

didSet 옵저버의 정의 구문
var <프로퍼티명>: <타입> [=<초기값>] {
    wilSet [(<인자명>)] {
            <프로퍼티 값이 변경되기 전에 실행할 내용
    }
}
  • 문법 형식에서 대괄호 []에 둘려 싸여서 표시되는 부분은 생략이 가능한 부분입니다.
  • didSet 옵저버도 willSet과 비슷한 특성을 가집니다. 이 옵저버는 프로퍼티에 값이 할당된 직후에 호출되는데, 새로 할당된 값이 아닌 기존에 저장되어 있던 값이 매개상수 형태로 전달된다. didSet 구현 블록 내에서 사용하기 위한 이름을 부여할 수 있지만, 생략하더라도 oldValue라는 이름으로 자동 전달되기 때문에 값을 사용하는 데는 아무런 문제가 없습니다.
  • didSet 구문에서 새로 할당된 값이 필요할 경우에는 프로퍼티 자체를 그냥 참조하면 됩니다.
  • didSet:  예전값 - oldValue를 참조, 새로운 값 - 프로퍼티 참조합니다.

 

willSet과 didSet

struct Job {
    var income: Int = 0 {
        willSet (newIncome) { // 바뀔 값이 바라미터로 전달.
            print("이번 달 월급은 \(newIncome)입니다.")
        }
        didSet(newIncome) {
            if income > newIncome { // 바뀌기 전의 과거값이 파라미터로 전달 (Income: 2000000 / newIncome = 1000000)
                print("월급이 \(income - newIncome) 증가했습니다.")
            }
            else {
                print("저런, 월급이 삼각되었군요...")
            }
            
        }
    }
}

var job = Job(income: 1000000) // 초기화시에는 willSet과 didSet이 호출되지는 않음
job.income = 2000000 // 이번 달 월급은 2000000입니다., 월급이 1000000 증가했습니다.
job.income = 1500000 // 이번 달 월급은 1500000입니다. 저런, 월급이 삼각되었군요...
  • willSet은 새 값이 저장되기 직전에 호출됩니다
  • didSet은 새 값이 저장된 직후에 호출됩니다

파라미터의 생략 - oldValue / newValue

struct Job {
    var income: Int = 0 {
        willSet { // 바뀔 값은 newValue
            print("이번 달 월급은 \(newValue)입니다.")
        }
        didSet {
            if income > oldValue { //바뀌기 전의 값은 oldvalue
                print("월급이 \(income - oldValue) 증가했습니다.")
            }
            else {
                print("저런, 월급이 삼각되었군요...")
            }
            
        }
    }
}

var job = Job(income: 1000000)
job.income = 2000000
job.income = 1500000

 

속성감시자의 사용 이유

  • 변수가 변할 때, 변경 내용을 반영하고 싶을 때(업데이트) - ex) 상태메시지 변경, 값이 변동되면 어떠한 기능을 호출할 때

 

속성감시자 정리

    • 저장속성 자체는 var로만 선언 가능합니다(let은 값이 변하지 않기 때문에, 관찰할 필요가 없음)
    • 자료형을 선언하는 것은 일반 변수와 동일합니다.(기본값을 넣으면 형식 추론 방식 가능)
    •  willSet 또는 didSet 중에서 한 가지만 구현하면 됩니다.(일반적으로 didSet으로 구현)
    • 지연저장 속성에 안됩니다. (스위프트 5.3 이후 업데이트: 지연 저장 속성에도 속성 감시자 구현 가능)

  속성 감시자를 추가 가능한 경우 인스턴스 속성

  •  저장 속성 (상속한 저장속성은 재정의 불가, 감시자 추가는 가능합니다.)
    - 상속한 저장속성은 재정의는 불가능하지만, 속성 감시자는 추가가 가능합니다..
  •  상속한 계산 속성을 재정의해 속성관찰자 추가 가능(단순 메서드 추가일 뿐)
    (본래의 계산속성에는 setter에서 값의 변경을 관찰가능 하므로 추가 불가)

계산속성에서 속성감시자 구현

class Temperature {
    var currentTemp: Double = 0.0
    
    var temp: Double {
        get {
            return currentTemp
        } set {
            willSet(newValue: newValue)
            let tempX = currentTemp
            currentTemp = temp
            didSet(oldValue: tempX)
            
        }
    }
    
    
    func willSet(newValue: Double) {
        print(newValue)
    }

    func didSet(oldValue: Double) {
        print(oldValue)
    }
}



let test = Temperature()

test.temp = 10

 

 

참고사항

willSet과 didSet의 동작 메커니즘

var x = 0


func willSet(newValue: Int) {
    print(newValue)
}

func didSet(oldValue: Int) {
    print(oldValue)
}


func setVar(newVar: Int) {
    willSet(newValue: newVar)
    let tempX = x
    x = newVar                       // 실제 값이 바뀌는 시점
    didSet(oldValue: tempX)
}


setVar(newVar: 10)
728x90

'iOS > Swift 문법' 카테고리의 다른 글

타입 메서드  (0) 2024.11.25
인스턴스 메서드  (0) 2024.11.25
타입속성 (Type Properties)  (0) 2024.11.22
계산/연산 속성(Computed property)  (0) 2024.11.22
지연 저장 속성 (Lazy Stored Properties)  (0) 2024.11.21