1. Property Observer

Apple 왈 : Property Observers(프로퍼티 옵저버)를 정의해서 프로퍼티 값의 변경을 모니터링 할 수 있습니다. 프로퍼티 옵저버는 자신이 정의한 "저장 프로퍼티"에 추가 할 수 있으며, super class(부모클래스)를 상속한 프로퍼티에도 추가 할 수 있습니다.

내가 관찰하는 프로퍼티에 값을 설정하려고 할때 변경을 감지한다. 심지어 새로운 값이 현재 값과 동일하더라도 속성 값이 설정되면 호출된다!

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

프로퍼티 옵저버에는 아래 두가지가 있고 제대로 설명을 해볼게욤! 값이 저장되기 직전에 🚨삐용삐용🚨 → willSet 값이 저장된 직후에 🚨삐용삐용🚨 → didSet

2. willSet

값이 저장되기 직전에 새로 저장될 값이 파라미터로 전달된다! 이때 파라미터 이름은 지정할 수 있지만 파라미터 이름과 괄호를 따로 지정하지 않을 경우 newValue 사용

class Human {
    var name: String = "이름 없음" {
        willSet(newName) {
            print("현재 이름은 \\(name)이지만 이제는 \\(newName)입니다!")
        }
    }
		//newValue를 사용해서!
		var age: Int = 200 {
        willSet {
            print("이제 내 나이는 \\(newValue)라고!!!")
        }
    }
}

let hidi: Human = .init()
print("willSet 전에 나의 이름은 \\(hidi.name)") // willSet 전에 나의 이름은 이름 없음
hidi.name = "안뇽히디" // 현재 이름은 이름 없음이지만 이제는 안뇽히디입니다!
print("willSet 후에 나의 이름은 \\(hidi.name)") // willSet 후에 나의 이름은 안뇽히디
hidi.age = 24 //이제 내 나이는 24라고!!!

3. didSet

값이 저장된 "직후"에 이전 프로퍼티의 값이 "파라미터"로 전달된다! 이때 파라미터 이름은 지정할 수 있지만, 파라미터 이름과 괄호를 따로 지정하지 않을 경우 oldValue로 사용한다

class Human {
    var name: String = "이름 없음" {
        didSet(oldName) {
            print("현재 이름은 \\(name)이지만 예전에는 \\(oldName)입니다!")
        }
    }
		//oldValue를 사용해서!
    var age: Int = 200 {
        didSet {
            print("예전에 내 나이는 \\(oldValue)라고!!!")
        }
    }
}

let hidi: Human = .init()
print("didSet 전에 나의 이름은 \\(hidi.name)") // didSet 전에 나의 이름은 이름 없음
hidi.name = "안뇽히디" // 현재 이름은 안뇽히디이지만 예전에는 이름 없음입니다!
print("didSet 후에 나의 이름은 \\(hidi.name)") // didSet 후에 나의 이름은 안뇽히디
hidi.age = 24 // 예전에 내 나이는 200라고!!!

+) 두개 같이 사용 가능?

A. 쌉가능

⭐️ 순서가 중요합니다! ⭐️

  1. willSet이 먼저 실행
  2. 저장 프로퍼티 name의 값 변경
  3. didSet 실행
class Human {
    var name: String = "이름 없음" {
        willSet(newName) {
            print("현재 이름은 \\(name)이지만 이제는 \\(newName)입니다!")
        }
        didSet(oldName) {
            print("현재 이름은 \\(name)이지만 예전에는 \\(oldName)입니다!")
        }
    }
    var age: Int = 200 {
        didSet {
            print("예전에 내 나이는 \\(oldValue)라고!!!")
        }
    }
}

let hidi: Human = .init()
print("값 변경 전에 나의 이름은 \\(hidi.name)")
hidi.name = "안뇽히디"
print("값 변경 후에 나의 이름은 \\(hidi.name)")
hidi.age = 24

4. 연산 프로퍼티에서의 프로퍼티 옵저버

가능하다. but 부모클래스의 연산 프로퍼티를 오버라이딩 할 경우에만! why? setter을 통해 값 변경 감지가 가능한데 굳이..?