property observer는 단어 그대로 '프로퍼티 관찰자'이다.
왜 관찰할까? 관찰하고 있던 property에 변동이 생겼을 때 필요한 작업을 하기 위함이다. didSet은 '관찰하고 있던 프로퍼티에 값이 셋팅 되었으니 무언가를 하자!' 이고 willSet은 '관찰하고 있던 프로퍼티에 값이 셋팅 되려고 하니 무언가를 하자!' 이다. did과 will이라는 단어 그대로다. 프로퍼티에 값이 '셋팅된 후'에 무언가를 하느냐와 값이 '셋팅 되려고 할 때' 무언가를 하느냐다. 그러면 '무엇'을 하면 좋을까?
아래는 스위프트 공식 문서의 Properties 챕터 중 property observer에 관한 샘플 코드다.
// 출처: https://docs.swift.org/swift-book/LanguageGuide/Properties.html
class StepCounter {
var totalSteps: Int = 0 {
willSet(newTotalSteps) {
print("About to set totalSteps to \(newTotalSteps)")
}
didSet {
if totalSteps > oldValue {
print("Added \(totalSteps - oldValue) steps")
}
}
}
}
let stepCounter = StepCounter()
stepCounter.totalSteps = 200
// About to set totalSteps to 200
// Added 200 steps
stepCounter.totalSteps = 360
// About to set totalSteps to 360
// Added 160 steps
stepCounter.totalSteps = 896
// About to set totalSteps to 896
// Added 536 steps
이걸 보면 '아 willSet은 값이 셋팅 되려고 할 때, didSet은 값이 셋팅된 후에 호출되는 구나' 를 쉽게 알 수 있다. 그런데 내가 조금 불만인 것은 실제로는 위의 예시처럼 print나 하려고 didSet, willSet을 사용하지 않는다는 것이다. 좀 더 실용적인 예제였으면 좋았을 것이다. 나도 사실 전에는 별 생각 없었는데 요즘 '100days of SwiftUI'라는 것을 하나씩 따라해보며 좀 더 스위프트를 만져보다 보니 오늘에서야 didSet, willSet을 실용적으로 써먹을 수 있는 방법을 하나 알게 되었다.
// 출처: https://www.hackingwithswift.com/books/ios-swiftui/making-changes-permanent-with-userdefaults
struct ExpenseItem: Identifiable, Codable {
var id = UUID() // generate UUID
let name: String
let type: String
let amount: Double
}
class Expenses: ObservableObject {
@Published var items = [ExpenseItem]() {
didSet {
if let encoded = try? JSONEncoder().encode(items) {
UserDefaults.standard.set(encoded, forKey: "Items")
}
}
}
init() {
// UserDefaults에 있는 데이터 가져와서 items 프로퍼티에 넣기...
}
}
위 코드를 보면 Expenses 클래스의 프로퍼티 items에 property observer인 didSet이 있다. 이것이 관찰하고 있는 items에 변경사항이 생길 때마다 didSet 부분이 호출되면서 items의 값을 UserDefaults에 저장한다. 이 코드를 봤을 때 '아 이런 종류(?)의 상황일 때 didSet을 사용하겠구나' 라는 느낌을 확실히 받았다. 단순히 didSet이 호출되었으니 print를 하는 것보단 좀 더 실무에 가까운 내용이라 이렇게 정리해보고 싶었다. 끝.
'swift & iOS > swift' 카테고리의 다른 글
[swift] ObservableObject 프로토콜과 swiftUI 뷰 (0) | 2022.03.24 |
---|---|
[swift] 시간, 날짜 출력하기 ( .dateTime, Date.now.formatted(...) ) (0) | 2022.03.15 |
[swift] api (0) | 2022.02.14 |
[swift] static 키워드: static이 붙은 프로퍼티와 메소드 (0) | 2022.02.14 |
[swift] set (0) | 2022.02.09 |