Swift Property Observers - didSet
概述
在 Swift 中,屬性觀察器(Property Observers)提供了一種監聽屬性值變化的機制。didSet 是其中一種觀察器,用於在屬性值被設定完成後執行特定的程式碼。
基本語法
var propertyName: Type = initialValue {
didSet {
// 屬性值改變後執行的程式碼
print("屬性已更新為: \(propertyName)")
}
}
willSet vs didSet
Swift 提供兩種屬性觀察器:
| 觀察器 | 執行時機 | 可存取的值 | 預設參數名稱 |
|---|---|---|---|
willSet | 屬性值即將改變前 | 新值 | newValue |
didSet | 屬性值改變後 | 舊值 | oldValue |
範例
var number: Int = 0 {
willSet {
print("即將把 number 從 \(number) 改成 \(newValue)")
}
didSet {
print("number 已從 \(oldValue) 改成 \(number)")
}
}
// 使用
number = 10
// 輸出:
// 即將把 number 從 0 改成 10
// number 已從 0 改成 10
實際應用場景
1. 基本用法
var score: Int = 0 {
didSet {
print("分數更新:\(oldValue) → \(score)")
// 可以觸發其他邏輯,如更新 UI、儲存到資料庫等
}
}
2. 與 @Published 的搭配使用
@Published var connectionState: ConnectionState = .initial {
didSet {
// 注意:@Published 已經自動處理 objectWillChange.send()
// 這裡的 didSet 通常用於額外的邏輯
if connectionState == .connected {
startHeartbeat()
}
}
}
3. 資料驗證與同步
var userName: String = "" {
didSet {
// 同步更新相關屬性
displayName = userName.isEmpty ? "匿名用戶" : userName
// 觸發 UI 更新
updateUserInterface()
}
}
重要注意事項
1. 與 @Published 的關係
@Published屬性包裝器已經自動處理了objectWillChange.send()- 在
@Published屬性上使用didSet時,通常不需要手動呼叫objectWillChange.send() didSet主要用於執行額外的業務邏輯
2. 避免無限遞迴
// ❌ 錯誤:可能造成無限遞迴
var value: Int = 0 {
didSet {
value = value + 1 // 這會再次觸發 didSet
}
}
// ✅ 正確:使用條件判斷
var value: Int = 0 {
didSet {
if value < 100 {
value = value + 1
}
}
}