在早期的 iOS 開發中,JSON 資料解析往往需要開發者手動逐層遍歷字典,這不僅耗時費力,極易因鍵值錯誤或類型不匹配導致崩潰。後來團隊引入了 Jastor 這個基於 Objective-C Runtime 的自動解析庫,極大地簡化了 Model 層的建構流程。本文將深入剖析 Jastor 的核心原理、優缺點,並分享實戰中遇到的坑與優化方案。
Jastor 的核心思想是利用 Runtime 機制,遍歷 Model 物件的所有屬性,以屬性名為 Key 從字典中取值,再根據 Value 的類型(NSDictionary、NSArray、NSString、NSNumber 等)決定是遞歸解析、陣列遍歷還是直接賦值。其核心流程如下:
propertyClassForPropertyName 獲取屬性對應的 Class,驗證是否為 Jastor 子類後遞歸調用 initWithDictOrArray:。屬性名_class 方法獲取元素類型,逐項解析(元素必須為字典)。setValue:forKey:。Jastor 大量使用 class_copyPropertyList、property_getAttributes 等 Runtime API 遍歷屬性。雖然 Runtime 反射效率較低,但作者引入了多層緩存機制:
readonly 屬性。propertyClassForPropertyName 查詢。這些簡單的字典緩存將解析效率提升了數個數量級,是典型的「以空間換時間」最佳實踐。
Jastor 採用類似組合模式的設計:父 Model 繼承 Jastor,其屬性也可以是繼承 Jastor 的子 Model。整個資料結構形成一棵 Model 樹,解析時自上而下遞歸,完美契合 JSON 的巢狀結構。這種設計讓複雜資料模型的建構變得極其優雅。
雖然 Jastor 內建基礎容錯(如空值跳過、唯讀屬性跳過),但實際專案中仍常因後端資料不穩定導致崩潰。常見問題及修正方案:
setValue:forKey: 前加入 isKindOfClass: 守衛,或嘗試轉型。dealWithArrayValue: 中增加 isKindOfClass:[NSDictionary class] 判斷,非字典則跳過或轉換。valueForKey: 並檢查 NSNull。新版 Jastor 引入 + (NSDictionary *)propertyMap 方法,允許屬性名與 JSON Key 不一致(如 user_name 對應 userName)。這對於對接多套後端 API、歷史欄位重命名極具價值。團隊同事「波波」早期即在舊版手動實現此機制,後來官方版本也正式支援。
Jastor 以極簡的程式碼實現了強大的自動解析,其遞歸思想、Runtime 應用、組合模式、緩存策略均值得學習。但在生產環境務必:
原始碼可至 GitHub 獲取。遇到崩潰請務必深入源碼定位,加入防護後再釋出。