Discover Observation in SwiftUI

更新於 發佈於 閱讀時間約 8 分鐘


New Zealand — Queenstown

New Zealand — Queenstown

What is Observation?


Observation 是 Swift 中用於追蹤屬性變化的新功能,透過 macro 對它們進行轉換。在 SwiftUI 裡針對特別的 property 發生變化時,才重新計算 View 的 body。

要使用非常簡單,加上 @Observable 即可,這就是依靠 macro 強大的力量,而且就不用使用 Property wrapper 了,例如 @State@Published

@Observable class FoodTruckModel {    

var orders: [Order] = []

var donuts = Donut.all

}

接下來介紹一個範例,在這個 var body: some View { ... 裡,只有用到 model.donuts 所以假設我們按下 Button ,整個 View 是會更新的。

但假設現在 Button 的功能,換成新增一個 order,但在 View 的 body 裡沒有使用到 orders 的話,整個 View 是不會更新,因為這個 orders 這個 property 是沒有被追蹤的。

raw-image

這種機制是 Observation 的一個重要優勢,它使得 SwiftUI 能夠精確地、選擇性地更新 UI,只重新計算那些真正受到資料變化影響的視圖部分,這能帶來顯著的效能提升。

不像舊的 ObservableObject 和 @Published 可能會導致更廣泛的視圖更新, @Observable 和 SwiftUI 的結合能夠實現更細粒度的更新控制。

那我們現在把它換成 computed property,看看會發生什麼事

我們現在對 FoodTruckModel 在新增一個 computed property, var orderCount: Int { orders.count }

@Observable class FoodTruckModel {
var orders: [Order] = []
var donuts = Donut.all
var orderCount: Int { orders.count }
}

struct DonutMenu: View {
let model: FoodTruckModel

var body: some View {
List {
Section("Donuts") {
ForEach(model.donuts) { donut in
Text(donut.name)
}
Button("Add new donut") {
model.addDonut()
}
}
Section("Orders") {
LabeledContent("Count", value: "\(model.orderCount)")
}
}
}
}

這時候以 View 的角度來看,我們追蹤的是 computed property orderCount,但是裡面訪問到了 orders 這屬性,這也表示 orders 屬性的變化,也會讓 UI 更新。

@Observation

  • Macro
  • Tracks access
  • Property changes cause UI updates

從中我們可以看到這提升了很大的效能

SwiftUI property wrappers


透過 Obserable SwiftUI 的 property wrappers 比以往更簡單, State , Environment , Bindable 變成三種主要與 SwiftUI 一起使用的 property wrappers。

首先介紹 State

使用 @State 修飾的 Model ,它的生命週期會由擁有它的 View 的生命週期來管理,表示與 View 一致。

範例: 在呈現一個 Sheet 時,會使用一個 @State 變數 (donutToAdd) 來綁定數值到可編輯的欄位上。這代表 donutToAdd 這個 Model 是這個 Sheet View 自己的狀態

raw-image


再來 Environment

它是可以全局訪問的值,可以再多個地方共享,像之前用 @EnvironmentObject 一樣,由 super view 傳至 sub view 。

raw-image


最後是 @Bindable

就像之前的 @Binding 一樣,假如這個 Model 是需要雙向綁定的,就是用它,像是要放在 TextField 的情境。

Lightweight

Connect references to UI

Uses $ syntax to create bindings

raw-image


小結

raw-image
  1. 這個 Model 需要成為 View 自身的狀態嗎?(讓 Model 與 View 生命週期一致)
    Yes: @State
    No:
  2. 這個 Model 需要成為 App 全局變數嗎?
    Yes: @Environment
    No:
  3. 這個 Model 只需要綁定嗎?
    Yes: @Bindable
    No:  var

Advanced uses


使用 @Observable 的 Model,在 SwiftUI 上讓 view body 使用,都有自動追蹤 model property 變化而更新 View 的能力。

但也有一些情況需要額外自行處理,如果這個 model 內有一個 computed property 不是由內部 stored property 組成,就需要額外2個步驟。

只有當要觀察的 property 不是透過 Observable 類型的 stored property 組合時,才需要。

這邊就是要手動額外寫

raw-image


Computed properties

  • SwiftUI Tracks access
  • Composed properties
  • Manual control when needed

ObservableObject


假如我們有舊的程式碼,是用 ObservableObject 的,但某天終於可以用 Observable ,我們可以看看如何更新程式碼,使用 Observable 。

範例1

raw-image

非常簡單,刪除 conform ObservableObject 以及 @Published 。

raw-image


在 View 方面

raw-image

也是一樣很簡單,刪除 @ObservedObject ,及 @EnvironmentObject 換成 @Environment

raw-image


所以轉換過程就只有3件事

  1. 換掉 conform ObservableObject ,改用 macro @Observable
  2. 刪除 property wrappers @Published
  3. 只用 @State , @Environment 和 @Bindable

關於從 Observable Object 的 Migrate,可參考官方文件

Resources


留言
avatar-img
留言分享你的想法!
avatar-img
CHENGYANG的沙龍
0會員
10內容數
CHENGYANG的沙龍的其他內容
2025/01/09
觀看 WWDC23 Write Swift macros 筆記 Overview Apple 一開始提出一個範例,把計算的過程顯示成字串,用一個 tuple 組合起來,但這種方式很明顯,有個大缺點,就是容易有人為疏失,導致錯誤發生,還無法用 compiler 檢查字串是否相等於左邊的算數。
Thumbnail
2025/01/09
觀看 WWDC23 Write Swift macros 筆記 Overview Apple 一開始提出一個範例,把計算的過程顯示成字串,用一個 tuple 組合起來,但這種方式很明顯,有個大缺點,就是容易有人為疏失,導致錯誤發生,還無法用 compiler 檢查字串是否相等於左邊的算數。
Thumbnail
2024/12/08
前言 常在寫 leet code 的朋友應該都知道,除了解出題目很重要,還有時間複雜度以及空間複雜度的問題,若能更理解時間複雜度,然後優化解法,就可以讓寫程式的基本底子更上一層樓,以下簡單介紹常見的時間複雜度以及演算法。 除了時間複雜度,也會順便簡單說明相關東西,如下: 相關演算法
Thumbnail
2024/12/08
前言 常在寫 leet code 的朋友應該都知道,除了解出題目很重要,還有時間複雜度以及空間複雜度的問題,若能更理解時間複雜度,然後優化解法,就可以讓寫程式的基本底子更上一層樓,以下簡單介紹常見的時間複雜度以及演算法。 除了時間複雜度,也會順便簡單說明相關東西,如下: 相關演算法
Thumbnail
2024/11/10
Why macros? 最早能從一些 protocol 發現這個特性(Derived protocol conformance),例如 Codable 這樣就可以避免寫重複樣版的程式碼 其實目前在 Swift 中已經有大量的例子,我們開發者只需要寫一些簡單的語法,編譯器就會自動生成一段複
Thumbnail
2024/11/10
Why macros? 最早能從一些 protocol 發現這個特性(Derived protocol conformance),例如 Codable 這樣就可以避免寫重複樣版的程式碼 其實目前在 Swift 中已經有大量的例子,我們開發者只需要寫一些簡單的語法,編譯器就會自動生成一段複
Thumbnail
看更多
你可能也想看
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
全球科技產業的焦點,AKA 全村的希望 NVIDIA,於五月底正式發布了他們在今年 2025 第一季的財報 (輝達內部財務年度為 2026 Q1,實際日曆期間為今年二到四月),交出了打敗了市場預期的成績單。然而,在銷售持續高速成長的同時,川普政府加大對於中國的晶片管制......
Thumbnail
全球科技產業的焦點,AKA 全村的希望 NVIDIA,於五月底正式發布了他們在今年 2025 第一季的財報 (輝達內部財務年度為 2026 Q1,實際日曆期間為今年二到四月),交出了打敗了市場預期的成績單。然而,在銷售持續高速成長的同時,川普政府加大對於中國的晶片管制......
Thumbnail
重點摘要: 6 月繼續維持基準利率不變,強調維持高利率主因為關稅 點陣圖表現略為鷹派,收斂 2026、2027 年降息預期 SEP 連續 2 季下修 GDP、上修通膨預測值 --- 1.繼續維持利率不變,強調需要維持高利率是因為關稅: 聯準會 (Fed) 召開 6 月利率會議
Thumbnail
重點摘要: 6 月繼續維持基準利率不變,強調維持高利率主因為關稅 點陣圖表現略為鷹派,收斂 2026、2027 年降息預期 SEP 連續 2 季下修 GDP、上修通膨預測值 --- 1.繼續維持利率不變,強調需要維持高利率是因為關稅: 聯準會 (Fed) 召開 6 月利率會議
Thumbnail
本文介紹瞭如何在SwiftUI中調整元件的對齊方式,包括置中、向左/向右/向上/向下對齊的方法。透過調整HStack、VStack以及frame的maxWidth、maxHeight和alignment屬性,可以達到想要的對齊效果。
Thumbnail
本文介紹瞭如何在SwiftUI中調整元件的對齊方式,包括置中、向左/向右/向上/向下對齊的方法。透過調整HStack、VStack以及frame的maxWidth、maxHeight和alignment屬性,可以達到想要的對齊效果。
Thumbnail
這個章節主要介紹了Swift程式語言中物件導向程式設計的基本概念,包括類別、建構子、公開、私有、受保護等等的概念。同時,也介紹了繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型和反射等進階特性。
Thumbnail
這個章節主要介紹了Swift程式語言中物件導向程式設計的基本概念,包括類別、建構子、公開、私有、受保護等等的概念。同時,也介紹了繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型和反射等進階特性。
Thumbnail
此章節旨在解釋Swift語言中函數的基本結構和操作方式,包括函數的聲明、呼叫、參數和返回值。閱讀這個章節可以幫助你理解並掌握如何在Swift編程中有效地使用和管理函數。
Thumbnail
此章節旨在解釋Swift語言中函數的基本結構和操作方式,包括函數的聲明、呼叫、參數和返回值。閱讀這個章節可以幫助你理解並掌握如何在Swift編程中有效地使用和管理函數。
Thumbnail
本篇介紹了Swift程式語言中的各種流程控制元素,包括條件語句(如if, else if, else),三元運算子,多條件分支判斷的switch語句,以及各種迴圈(如for迴圈,while迴圈,以及repeat-while迴圈)。同時也詳細解釋了如何進行迴圈嵌套,以及如何使用控制迴圈語句。
Thumbnail
本篇介紹了Swift程式語言中的各種流程控制元素,包括條件語句(如if, else if, else),三元運算子,多條件分支判斷的switch語句,以及各種迴圈(如for迴圈,while迴圈,以及repeat-while迴圈)。同時也詳細解釋了如何進行迴圈嵌套,以及如何使用控制迴圈語句。
Thumbnail
本章節介紹了如何建立並設置Swift項目以及如何選擇和設置Swift代碼編輯器。這包括在Xcode和命令行中建立Swift項目,選擇Xcode、Visual Studio Code或AppCode作為編輯器,以及如何使用SPM安裝插件。
Thumbnail
本章節介紹了如何建立並設置Swift項目以及如何選擇和設置Swift代碼編輯器。這包括在Xcode和命令行中建立Swift項目,選擇Xcode、Visual Studio Code或AppCode作為編輯器,以及如何使用SPM安裝插件。
Thumbnail
本章節旨在為讀者提供Swift程式語言的基礎知識,包括其基本語法、註解方法和變數使用方式,並通過具體的程式碼示例來說明這些概念。這將幫助讀者理解Swift的基本結構,並學會如何在Swift中定義變數並使用註解。
Thumbnail
本章節旨在為讀者提供Swift程式語言的基礎知識,包括其基本語法、註解方法和變數使用方式,並通過具體的程式碼示例來說明這些概念。這將幫助讀者理解Swift的基本結構,並學會如何在Swift中定義變數並使用註解。
Thumbnail
這份文件的目的是介紹Swift語言,包括它的特性、應用範疇,以及誰在使用它。它也提供了一些學習Swift的資源和工具,以及一些常見的Swift庫和框架。
Thumbnail
這份文件的目的是介紹Swift語言,包括它的特性、應用範疇,以及誰在使用它。它也提供了一些學習Swift的資源和工具,以及一些常見的Swift庫和框架。
Thumbnail
Part.1 搞定基本的 UI 開始開發 iOS App。 首先準備一台 Mac,然後安裝 Xcode,新增專案,系統即刻生成基本的專案結構。coding 的起點在檔案 ContentView.swift: import SwiftUI struct ContentView: View {  
Thumbnail
Part.1 搞定基本的 UI 開始開發 iOS App。 首先準備一台 Mac,然後安裝 Xcode,新增專案,系統即刻生成基本的專案結構。coding 的起點在檔案 ContentView.swift: import SwiftUI struct ContentView: View {  
Thumbnail
觀察者模式透過主題訂閱/訊息通知的機制,極度增強系統的可擴展性、靈活性以及降低組件間的耦合度。概念直觀簡單,是非常實用的設計模式。
Thumbnail
觀察者模式透過主題訂閱/訊息通知的機制,極度增強系統的可擴展性、靈活性以及降低組件間的耦合度。概念直觀簡單,是非常實用的設計模式。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News