SwiftUI:屬性包裝器@StateObject的使用示例

@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的一個新示例。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容