HandyJSON原理

HandyJSON 的優勢

JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式, 應用廣泛. 在 App 的使用過程中, 服務端給移動端發送的大部分都是 JSON 數據, 移動端需要解析數據才能做進一步的處理. 在解析JSON數據這一塊, 目前 Swift 中流行的框架基本上是 SwiftyJSON, ObjectMapper, JSONNeverDie, HandyJSON 這么幾種.

我們應該如何選擇呢?

首先我們應該先明白解析 JSON 的原理. 目前有兩個方向.

保持 JSON 語義, 直接解析 JSON.
SwiftyJSON 就是這樣的. 本質上仍然需要根據 JSON 結構去取值.

預定義 Model 類, 將 JSON 反序列化類的實例, 再使用這些實例.
這種方式和 OC 中的 MJExtension 的思路是一致的. 在 Swift 中, ObjectMapper, JSONNeverDie, 以及 HandyJSON 做的都是將 JSON 文本反序列化到 Model 類上.

第二種思路是我們熟悉和比較方便的. 和服務端定義好數據結構, 寫好 Model 就可以直接解析.

第二種思路有三種實現方式:

完全沿用 OC 中的方式, 讓 Model 類繼承自 NSObject, 通過 class_copyPropertyList 方法拿到 Model 的各種屬性, 從 JSON 中拿到對應的 value, 再通過 OC 中 利用runtime 機制 實現的 KVC 方法為屬性賦值. 如 JSONNeverDie.
支持純 Swift 類, 但要求開發者實現 mapping 函數, 使用重載的運算符進行賦值, 如 ObjectMapper.
獲取到 JSON 數據后, 直接在內存中為實例的屬性賦值. HandyJSON 就是這樣實現的.
第一種方式的缺點在于需要強制繼承 NSObject, 這不適用于 struct 定義的 Model. 因為 struct 創建的 Model 不能通過 KVC 為其賦值.
第二種方式的缺點在于自定義 mapping 函數, 維護比較困難.
第三種方式在使用上和 MJExtension 基本差不多, 比較方便. 是我們所推薦的.

HandyJSON 解析數據的原理.

如何在內存上為實例的屬性賦值呢?
為屬性賦值, 我們需要以下步驟:

獲取到屬性的名稱和類型.
找到實例在內存中的 headPointer, 通過屬性的類型計算內存中的偏移值, 確定屬性在內存中的位置.
在內存中為屬性賦值.
在 Swift 中實現反射機制的類是 Mirror, 通過 Mirror 類可以獲取到類的屬性, 但是不能為屬性賦值, 它是可讀的. 但是我們可以直接在內存中為實例賦值. 這是一種思路. 另外一種思路是不利用 Mirror, 直接在內存中獲取到屬性的名稱和類型, 這也是可以的. 目前 HandyJSON 就是利用的第二種方式.

1. 核心原理:繞過反射,直接操作內存

傳統的 JSON 庫(如 ObjectMapper)依賴 Swift 的 Mirror 反射機制遍歷模型屬性,但反射存在性能瓶頸且無法直接修改屬性值。HandyJSON 通過以下方式實現高效解析:

a. 利用類型元數據(Type Metadata)
  • Swift 編譯器會為每個類型生成元數據,包含屬性名稱、類型、內存偏移量等信息。
  • HandyJSON 直接訪問這些元數據,獲取屬性的名稱內存位置,無需通過反射。
  • 例如,結構體的屬性在內存中是連續排列的,通過元數據可以計算出每個屬性的偏移量。
b. 內存拷貝與指針操作
  • 通過 UnsafeMutablePointer 直接操作模型實例的內存。

  • 將 JSON 值轉換為目標類型后,直接寫入對應的內存地址。

  • 示例代碼邏輯:

    swift

    let offset = getPropertyOffset(from: metadata) // 獲取屬性偏移量
    let pointer = instancePointer + offset          // 計算屬性內存地址
    let value = parseJSONValue(...)                // 解析 JSON 值
    pointer.storeBytes(of: value, as: type)         // 直接寫入內存
    

2. 實現步驟詳解

a. 類型元數據解析
  • 獲取類型信息:通過 type(of:) 或泛型類型參數獲取類型的元數據。
  • 解析屬性列表:從元數據中提取屬性名稱、類型、是否為可選類型(Optional)等信息。
  • 處理繼承和協議:遍歷類型的繼承鏈,確保父類屬性也能被正確映射。
b. JSON 到內存的映射
  1. 解析 JSON:將 JSON 數據轉換為字典([String: Any])。
  2. 匹配鍵與屬性:將 JSON 的鍵與模型屬性名匹配(支持自定義鍵名映射)。
  3. 類型轉換:將 JSON 值轉換為目標屬性類型(如 String 轉 Int、處理嵌套模型等)。
  4. 內存寫入:通過指針將轉換后的值寫入模型實例的內存。
c. 特殊類型處理
  • 可選類型(Optional):根據 JSON 是否存在鍵值決定是否寫入 nil
  • 枚舉(Enum):將 JSON 值映射到枚舉的 rawValue 或關聯值。
  • 泛型類型:需要特殊處理元數據的動態解析。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/74383.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/74383.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/74383.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

信號的產生和保存

信號的產生 信號就是操作系統對用戶操作做出的反應,但它的本質就是往操作系統寫入信號,這是由操作系統的結構決定的。通過修改比特位來告訴操作系統接收信號和傳了幾號信號。 也正是因為我們身為用戶無法親自修改內核數據,所以我們需要通過操…

在C++ Qt中集成Halcon窗口并實現跨平臺兼容和大圖加載

目錄 1. Halcon窗口嵌入Qt Widget 2. 處理大圖加載 3. 多線程優化顯示 4. 跨平臺兼容性 1. Halcon窗口嵌入Qt Widget 將Halcon的HWindow控件嵌入到Qt的QWidget容器中,利用系統原生句柄實現跨平臺。 #include <HalconCpp.h> #include <QWidget>class HalconWi…

深度學習技術與應用的未來展望:從基礎理論到實際實現

深度學習作為人工智能領域的核心技術之一&#xff0c;近年來引起了極大的關注。它不僅在學術界帶來了革命性的進展&#xff0c;也在工業界展現出了廣泛的應用前景。從圖像識別到自然語言處理&#xff0c;再到強化學習和生成對抗網絡&#xff08;GAN&#xff09;&#xff0c;深度…

藍光三維掃描技術:汽車零部件檢測的精準高效之選

——汽車方向盤配件、保險杠塑料件、鈑金件檢測項目 汽車制造工業的蓬勃發展&#xff0c;離不開強大的零部件制造體系作支撐。汽車零部件作為汽車工業的基礎&#xff0c;其設計水平、制造工藝、質量控制手段逐漸與國際標準接軌&#xff0c;對于零部件面差、孔位、圓角、特征線…

數據庫聯表Sql語句建一個新表(MySQL,Postgresql,SQL server)

數據庫聯表Sql語句建一個新表(MySQL,Postgresql,SQL server) 如果你想基于 SELECT USERS.ID,USERS.NAME,USERS.EMAIL,USERS.ID_CARD,USERS.V_CARD,USERS.ADDRESS,v_card.type,v_card.amount FROM USERS JOIN v_card on USERS.V_CARDv_card.v_card 這個查詢結果創建一個新表&am…

六十天前端強化訓練之第三十天之深入解析Vue3電商項目:TechStore全棧實踐(文結尾附有源代碼)

歡迎來到編程星辰海的博客講解 看完可以給一個免費的三連嗎&#xff0c;謝謝大佬&#xff01; 目錄 深入解析Vue3電商項目&#xff1a;TechStore全棧實踐 一、項目架構設計 二、核心功能實現 三、組合式API深度實踐 四、性能優化實踐 五、項目擴展方向 六、開發經驗總結…

【人工智能】機器學習中的評價指標

機器學習中的評價指標 在機器學習中&#xff0c;評估指標&#xff08;Evaluation Metrics&#xff09;是衡量模型性能的工具。選擇合適的評估指標能夠幫助我們更好地理解模型的效果以及它在實際應用中的表現。 一般來說&#xff0c;評估指標主要分為三大類&#xff1a;分類、…

不同機床對螺桿支撐座的要求有哪些不同?

螺桿支撐座是機械設備中重要的支撐部件&#xff0c;其選擇直接影響到設備的穩定性和使用壽命&#xff0c;尤其是在機床中&#xff0c;不同的機床對螺桿支撐座的要求也是不同的。 1、精度&#xff1a;精密測量用的基準平面和精密機床機械的檢驗測量設備&#xff0c;需要使用高精…

在Spring Boot中,可以通過實現一些特定的接口來拓展Starter

在Spring Boot中&#xff0c;開發者可以通過實現一些特定的接口來拓展Starter。這些接口允許開發者自定義Spring Boot應用程序的配置和行為&#xff0c;從而創建功能豐富且易于使用的Starter。以下是一些關鍵的接口&#xff0c;用于拓展Starter&#xff1a; EnvironmentPostPro…

深入理解 tree 命令行工具:目錄結構可視化的利器

文章目錄 前言1. 什么是 tree 命令&#xff1f;安裝 tree 2. tree 的基本用法顯示當前目錄的樹狀結構顯示指定目錄的樹狀結構 3. tree 的常用選項3.1 顯示隱藏文件3.2 排除特定目錄或文件3.3 限制遞歸深度3.4 顯示文件大小3.5 顯示文件的權限信息3.6 將輸出保存到文件 4. 實際應…

Federated learning client selection algorithm based on gradient similarity閱讀

基于梯度相似性的聯邦學習客戶端選擇算法 Abstract 摘要introduction**背景****目的****結論****結果****討論****思路** 鏈接&#xff1a;https://link.springer.com/article/10.1007/s10586-024-04846-0 三區 Abstract 摘要 聯邦學習&#xff08;FL&#xff09;是一種創新的…

【測試工具】如何使用 burp pro 自定義一個攔截器插件

在 Burp Suite 中&#xff0c;你可以使用 Burp Extender 編寫自定義攔截器插件&#xff0c;以攔截并修改 HTTP 請求或響應。Burp Suite 支持 Java 和 Python (Jython) 作為擴展開發語言。以下是一個完整的流程&#xff0c;介紹如何創建一個 Burp 插件來攔截請求并進行自定義處理…

網絡編程的概念&作用

網絡編程是什么&#xff1f; 想象一下&#xff0c;你和朋友在不同的房間里&#xff0c;你們想互相傳遞紙條聊天。網絡編程就像是編寫一套規則&#xff0c;讓計算機能夠通過網絡&#xff08;比如互聯網&#xff09;互相傳遞信息。這些信息可以是文字、圖片、視頻&#xff0c;甚…

航天軍工與金融行業 UE/UI 設計:跨越領域的體驗革新之道

在數字化時代&#xff0c;用戶體驗&#xff08;UE&#xff09;和用戶界面&#xff08;UI&#xff09;設計成為眾多行業提升競爭力的關鍵因素。航天軍工與金融行業雖業務性質差異巨大&#xff0c;但在 UE/UI 設計方面卻面臨著一些相似挑戰&#xff0c;同時也在各自的探索中展現出…

【Git】--- 分支管理

Welcome to 9ilks Code World (??? ? ???) 個人主頁: 9ilk (??? ? ???) 文章專欄&#xff1a; Git 本篇博客我們來介紹Git的一個重要功能之一 ---- 分支。我們將講解關于分支的各種操作&#xff0c;以及如何幫助我們進行開發。 &#x1f3e0; 理解分支…

純血鴻蒙:中國操作系統自主創新的里程碑

引言&#xff1a;破局者登場 2024 年 10 月&#xff0c;搭載純血鴻蒙操作系統&#xff08;HarmonyOS NEXT&#xff09;的華為 Mate 70 系列正式發布&#xff0c;首日預約量突破 330 萬。這場現象級熱度的背后&#xff0c;不僅是消費者對硬件創新的期待&#xff0c;更是中國科技…

二造考試的備考過程中如何保持良好的心態?

在二級造價師考試的備考過程中&#xff0c;保持良好的心態至關重要&#xff0c;以下是一些有效的方法&#xff1a; 樹立正確的考試觀念 )認識到二級造價師考試是職業生涯中的一個重要環節&#xff0c;但不是唯一的決定因素。把它看作是提升自己專業能力、豐富知識儲備的機會&am…

Vue3前端開發:組件化設計與狀態管理

Vue3前端開發&#xff1a;組件化設計與狀態管理 一、Vue3組件化設計 組件基本概念與特點 是一款流行的JavaScript框架&#xff0c;它支持組件化設計&#xff0c;這意味著我們可以將頁面分解成多個獨立的組件&#xff0c;每個組件負責一部分功能&#xff0c;通過組件的嵌套和復用…

動手學深度學習11.9. Adadelta-筆記練習(PyTorch)

以下內容為結合李沐老師的課程和教材補充的學習筆記&#xff0c;以及對課后練習的一些思考&#xff0c;自留回顧&#xff0c;也供同學之人交流參考。 本節課程地址&#xff1a;72 優化算法【動手學深度學習v2】_嗶哩嗶哩_bilibili 本節教材地址&#xff1a;11.9. Adadelta —…

Android Audio基礎(13)——audiomixer

在 Android 平臺上&#xff0c;音頻混合器 AudioMixer 主要用在 AudioFlinger 里&#xff0c;將多路音頻源數據混音&#xff08;包括混音、音量處理、重采樣及處理聲道等&#xff09;。位于 framework 的音頻處理模庫 libaudioprocessing&#xff08;frameworks/av/media/libau…