@StateObject 用于創(chuàng)建并持有 ObservableObject 對象,確保其生命周期與視圖相同。
- @StateObject 專門用于管理符合 ObservableObject 協(xié)議的實例。
- 標(biāo)注的對象實例在視圖的整個生命周期中保持唯一,即使視圖更新,對象實例也不會重新創(chuàng)建。
作用:@StateObject 用于在視圖中創(chuàng)建一個持久化的可觀察對象,專門用于管理符合 ObservableObject 協(xié)議的實例,并在視圖的生命周期內(nèi)保持持久性。它類似于@ObservedObject,但在對象生命周期中只會創(chuàng)建一次,標(biāo)注的對象實例在視圖的整個生命周期中保持唯一,即使視圖更新,對象實例也不會重新創(chuàng)建。
應(yīng)用場景
-
@StateObject通常在視圖樹中最頂層使用,用于創(chuàng)建和維護 ObservableObject 實例。 - 常用于需要在視圖的整個生命周期中持續(xù)存在的數(shù)據(jù)模型或業(yè)務(wù)邏輯。
- 相較
@State而言,@StateObject更適合管理復(fù)雜的數(shù)據(jù)模型及其執(zhí)行邏輯
注意事項
-
@StateObject觸發(fā)視圖更新的條件包括使用@Published標(biāo)注的屬性被賦值和調(diào)用objectWillChange發(fā)布者。 - 只在必須響應(yīng)實例屬性變化的視圖中使用
@StateObject,如果僅需讀取數(shù)據(jù)而不需要觀察變化,可考慮其他選項。 - 引入
@StateObject意味著所有相關(guān)操作都在主線程上進行( SwiftUI 會隱式為視圖添加@MainActor),包括異步操作。應(yīng)將需要在非主線程上運行的代碼應(yīng)該從視圖代碼中剝離。 - 如果在視圖存續(xù)期有保障的地方創(chuàng)建實例( 比如說 App 層級),且在當(dāng)前層級也無需響應(yīng)該實例中屬性的變化,可以不使用 @StateObject。
使用示例
class TimerData: ObservableObject {
@Published var timeCount = 0
}
struct TimerView: View {
@StateObject var timer = TimerData()
var body: some View {
Text("Time: \(timer.timeCount)")
}
}
在下面的示例中,我們創(chuàng)建一個 DataModel 類,并使用 @StateObject 在視圖中創(chuàng)建和使用該對象
class DataModel: ObservableObject {
@Published var data: [String] = []
}
struct ContentView: View {
@StateObject var dataModel = DataModel()
var body: some View {
VStack {
Button(action: {
dataModel.data.append("New Item")
}) {
Text("Add Item")
}
ForEach(dataModel.data, id: \.self) { item in
Text(item)
}
}
}
}
@StateObject和@ObservedObject區(qū)別:
@SateObject針對引用類型設(shè)計,被View持有,當(dāng)View更新時,實例不會被銷毀,與State類似,使得View本身擁有數(shù)據(jù),這使得 @StateObject 適用于那些需要持久狀態(tài)且與視圖密切相關(guān)的數(shù)據(jù)對象,比如頁面導(dǎo)航、用戶輸入等。@StateObject告訴SwiftUI,當(dāng)這個視圖更新時,你希望保留這個對象的一個示例
@ObservedObject只是作為View的數(shù)據(jù)依賴,不被View持有,View更新時ObservedObject對象可能會被銷毀,適合數(shù)據(jù)在SwiftUI外部存儲,把@ObservedObject包裹的數(shù)據(jù)作為視圖的依賴,比如數(shù)據(jù)庫中存儲的數(shù)據(jù),當(dāng)SwiftUI視圖“更新”時,實際發(fā)生的是創(chuàng)建并顯示視圖的新示例。
這意味著當(dāng)您通過@ObservableObject聲明視圖模型時,您將獲得數(shù)據(jù)對象Model的一個新示例。