@@ -21,18 +21,32 @@ class DecodingCache: Cachable {
2121 /// - Parameter type: The Decodable type to cache
2222 func cacheSnapshot< T> ( for type: T . Type , codingPath: [ CodingKey ] ) {
2323
24- // 减少动态派发开销,is 检查是编译时静态行为,比 as? 动态转换更高效。
25- guard type is SmartDecodable . Type else { return }
2624
27- if let object = type as? SmartDecodable . Type {
28- let snapshot = DecodingSnapshot ( )
29- snapshot. codingPath = codingPath
30- // [initialValues] Lazy initialization:
31- // Generate initial values via reflection only when first accessed,
32- // using the recorded objectType to optimize parsing performance.
33- snapshot. objectType = object
34- snapshots. append ( snapshot)
25+
26+ let smartType : SmartDecodable . Type ?
27+
28+ /** 缓存条件
29+ * 1. 直接是 SmartDecodable
30+ * 2. 是属性包装器,且 WrappedValue 是 SmartDecodable
31+ * 3. 其它情况,不关心
32+ */
33+ if let objectType = type as? SmartDecodable . Type {
34+ smartType = objectType
35+ } else if let wrapperType = type as? any PropertyWrapperable . Type {
36+ smartType = wrapperType. wrappedSmartDecodableType
37+ } else {
38+ return
3539 }
40+
41+ guard let object = smartType else { return }
42+
43+ let snapshot = DecodingSnapshot ( )
44+ snapshot. codingPath = codingPath
45+ // [initialValues] Lazy initialization:
46+ // Generate initial values via reflection only when first accessed,
47+ // using the recorded objectType to optimize parsing performance.
48+ snapshot. objectType = object
49+ snapshots. append ( snapshot)
3650 }
3751
3852 /// Removes the most recent snapshot for the given type
@@ -52,11 +66,6 @@ extension DecodingCache {
5266 /// 该方法会根据传入的 `codingPath`(代表某个解码容器的位置),
5367 /// 在缓存的快照中查找对应容器,并尝试获取该容器中 `key` 对应字段的初始值。
5468 /// 如果该容器尚未初始化初始值,则会延迟初始化一次(通过反射等方式)。
55- ///
56- /// - Parameters:
57- /// - key: 要查找的字段对应的 `CodingKey`,若为 `nil` 则直接返回 `nil`。
58- /// - codingPath: 当前字段所在的容器路径,用于准确定位容器上下文。
59- /// - Returns: 若存在可用的初始值且类型匹配,则返回该值;否则返回 `nil`。
6069 func initialValueIfPresent< T> ( forKey key: CodingKey ? , codingPath: [ CodingKey ] ) -> T ? {
6170
6271 guard let key = key else { return nil }
0 commit comments