스위프트의 속성 관찰자(property observers)는 속성 값의 변경에 반응할 수 있게 해줍니다. 이 개념은 스위프트와 함께 등장하여 데이터 변경에 대한 투명한 제어와 변경 시 자동화된 로직을 강화하기 위해 만들어졌습니다.
질문의 역사:
스위프트 이전에는 이러한 동작이 setter나 특별한 메서드를 통해 수동으로 구현되는 경우가 많았습니다. 스위프트에서는 이러한 관찰자가 언어의 표준 도구로 등장했습니다.
문제:
개발자는 속성이 변경되는 시점을 포착할 수 있어야 하며, 예를 들어 UI를 업데이트하거나 데이터 유효성을 검사하는 작업이 필요합니다. 관찰자가 없으면 코드는 더 복잡하고 읽기 어려워집니다.
해결책:
스위프트에는 두 가지 주요 관찰자가 있습니다:
willSet은 값이 변경되기 전에 호출됩니다.didSet은 새 값이 할당된 후에 호출됩니다.관찰자는 stored property에 추가할 수 있으며, lazy 속성과 computed 속성은 제외됩니다.
코드 예시:
class Temperature { var celsius: Double { willSet { print("곧 새로운 값이 설정됩니다: ", newValue) } didSet { print("이전 값은:", oldValue, ", 새로운 값은:", celsius) } } init(celsius: Double) { self.celsius = celsius } } let temp = Temperature(celsius: 22) temp.celsius = 28 // willSet과 didSet이 호출됩니다.
주요 특징:
관찰자를 computed 속성에 추가할 수 있나요?
아니요, computed 속성에는 willSet과 didSet을 추가할 수 없습니다. 이미 자체 게터와 세터가 있기 때문입니다. willSet/didSet은 오직 stored 속성에만 해당됩니다.
초기화기에서 속성을 변경할 때 관찰자들이 호출되나요?
아니요, property observers는 초기화(init) 동안 호출되지 않습니다. 초기화가 완료된 후 값이 변경될 때만 작동합니다.
현재 값을 자기 자신에게 할당할 때, 예를 들어 x = x?
관찰자는 값이 변경되지 않았더라도 여전히 호출됩니다! 이는 부작용을 초래할 수 있으니 주의해야 합니다.
var value: Int = 0 { didSet { print("didSet은 항상 호출됩니다!") } } value = value // didSet이 호출됩니다.
개발자가 didSet에서 UI 업데이트를 수행했지만, 값의 변경을 확인하지 않았습니다. UI는 "빈" 할당에도 업데이트되어 성능이 저하되었습니다.
장점:
단점:
didSet에서 이전 값과 새로운 값의 동등성을 검사했습니다. 값이 실제로 변경된 경우에만 UI가 업데이트되었습니다.
장점:
단점: