日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

SwiftUI之深入解析属性包装器如何处理结构体

發(fā)布時間:2024/5/21 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SwiftUI之深入解析属性包装器如何处理结构体 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
  • 已經(jīng)了解了 SwiftUI 如何通過使用 @State 屬性包裝器將變化的數(shù)據(jù)存儲在結(jié)構(gòu)體中,如何使用 $ 將狀態(tài)綁定到 UI 控件的值,以及更改 @state 包裝的屬性時是如何自動讓 SwiftUI 重新調(diào)用結(jié)構(gòu)體的 body 屬性的。
  • 所有這些結(jié)合在一起,可以編寫如下代碼:
struct ContentView: View {@State private var blurAmount: CGFloat = 0var body: some View {VStack {Text("Hello, World!").blur(radius: blurAmount)Slider(value: $blurAmount, in: 0...20)}} }
  • 如果執(zhí)行這些代碼,將會發(fā)現(xiàn)左右拖動滑塊可以完全按照預(yù)期調(diào)整文本標(biāo)簽的模糊量。現(xiàn)在,假設(shè)我們希望該綁定不僅僅是處理模糊效果的半徑,想將其保存到 UserDefaults 中,運(yùn)行一個方法,或者只是打印出該值以進(jìn)行調(diào)試,可以嘗試像這樣更新屬性:
@State private var blurAmount: CGFloat = 0 {didSet {print("New value is \(blurAmount)")} }
  • 如果運(yùn)行該代碼,可能會出現(xiàn)失望的結(jié)果:當(dāng)拖動滑塊周圍時,會看到模糊量的變化,但是不會看到我們的 print() 語句被觸發(fā),實際上什么都不會輸出。
  • 為了了解這里的原因,可以考慮一下在使用 Core Data 時:使用 @FetchRequest 屬性包裝器查詢我們的數(shù)據(jù),以及如何直接使用 FetchRequest 結(jié)構(gòu)體,以便可以更好地控制它是如何創(chuàng)建的。
  • 屬性包裝器具有該名稱,因為它們將我們的屬性包裝在另一個結(jié)構(gòu)體中。對于許多屬性包裝器而言,該結(jié)構(gòu)體與包裝器本身具有相同的名稱,但是使用 @FetchRequest 時展示了實際上是如何實際讀取其中的包裝值,獲取的結(jié)果,而不是請求本身。
  • 這意味著當(dāng)使用 @State 來包裝字符串時,最終得到的實際屬性類型是 State。類似地,當(dāng)使用 @Environment 和其他環(huán)境時,我們最終得到一個 Environment 類型的結(jié)構(gòu)體,該結(jié)構(gòu)體內(nèi)部包含一些其他值。
  • 之前曾解釋說,我們無法在視圖中修改屬性,因為它們是結(jié)構(gòu)體,因此是固定的。但是,現(xiàn)在知道 @State 本身會生成一個結(jié)構(gòu)體,因此面臨一個難題:如何修改該結(jié)構(gòu)體?
  • Xcode 有一個非常有用的命令,稱為“快速打開”(使用 Cmd + Shift + O 進(jìn)行訪問),該命令可以在項目或已導(dǎo)入的任何框架中找到任何文件或類型?,F(xiàn)在將其激活,然后輸入 “State”,希望第一個結(jié)果在其下方顯示 SwiftUI,但如果沒有,請找到并選擇它:

  • 將進(jìn)入 SwiftUI 生成的界面,該界面實質(zhì)上是 SwiftUI 向我們展示的所有的部分。那里沒有實現(xiàn)代碼,只有協(xié)議,結(jié)構(gòu)體,修飾符等的許多定義。
  • 我們可以查看 state,因此應(yīng)該被帶到此行:
@propertyWrapper public struct State<Value> : DynamicProperty {
  • 該 @propertyWrapper 屬性使它成為 @State 供我們使用,現(xiàn)在往下看幾行,可以看到以下內(nèi)容:
public var wrappedValue: Value { get nonmutating set }
  • 該包裝值是我們要存儲的實際值,例如字符串,這個生成的接口告訴我們,該屬性可以讀取(get)和寫入(set),但是當(dāng)設(shè)置該值時,它實際上不會更改結(jié)構(gòu)體本身。在后臺,它將值發(fā)送給SwiftUI以便存儲在可以自由修改的位置,因此,結(jié)構(gòu)體本身永不改變。
  • 現(xiàn)在知道了所有這些,讓我們回到問題代碼:
@State private var blurAmount: CGFloat = 0 {didSet {print("New value is \(blurAmount)")} }
  • 在表面上,狀態(tài)為“ 當(dāng)blurAmount 更改時,打印出它的新值”。但是,由于 @State 實際上會包裝其內(nèi)容,因此實際上是說,當(dāng)包裝 blurAmount 的 State 結(jié)構(gòu)體更改時,請打印出新的模糊量。
  • 還在這兒?現(xiàn)在讓我們更進(jìn)一步:已經(jīng)看到 State 如何使用一個非可變的 setter 包裝其值,這意味著 blurAmount 或包裝它的 State 結(jié)構(gòu)體都沒有改變,我們的綁定直接改變了內(nèi)部存儲的值,這意味著屬性觀察者永遠(yuǎn)不會被觸發(fā)。
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的SwiftUI之深入解析属性包装器如何处理结构体的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。