swfit进阶-11-swift中的Mirror的原理
「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战」。
- 之前我们了解了
Mirror
的使用方法,以及通过Mirror解析Json
,转换为model。本文主要介绍下Mirror
的原理
1. 源码分析
- 在
Mirror.swift
文件中找到Mirror
,是一个结构体类型
其初始化方法中,先判断传入的对象subject
是否遵循CustomReflectable
协议,如果符合的话则通过customMirror
确定对象的属性。否则通过internalReflecting
的方法进行初始化。
- internalReflecting
查看
主要是:1.通过
_getNormalizedType
方法获取传入的subject
的类型2.获取对象的属性个数,并遍历属性存储到字典中。3.设置获取父类的 Mirror
,继承的关系因此Mirror有个superclassMirror
的属性,会返回该类的父类。4.设置Miroor
的displayStyle
属性。5.设置 subjectType
和_defaultDescendantRepresentation
属性。
- 查看
_getNormalizedType
的实现
函数上面使用了一个编译字段
@_silgen_name
,这个是 Swift 的一个隐藏符号
,作⽤是将某个C/C++
函数直接映射为 Swift 函数
。也就是我们在调用 _getNormalizedType
函数的时候,最终会调用C++中的swift_reflectionMirror_normalizedType -> Call
方法
我们看下
call
的实现
主要分为类的调用和非类的调用,对于非类的impl实现通过一个枚举进行判断
ReflectionMirrorImpl
,它通过 kind
来判断实例的类型,从而拿到不同类型对应的 impl
,调用非类的 call(&impl)
。而类是调用 callClass
。
ReflectionMirrorImpl
的种类主要有以下几种:
- TupleImpl 元组的反射
- StructImpl 结构体的反射
- EnumImpl 枚举的反射
- ClassImpl 类的反射
- MetatypeImpl 元数据的反射
- OpaqueImpl 不透明类型的反射
我们以StructImpl
为例子查看
通过
isReflectable
函数来判断是否接受反射,它的实现无非就是拿到 Description
,通过 Description
的 isReflectable
函数来判断的。在获取 count
的时候用到了 isReflectable
函数,代码如下:
如果不支持反射,直接返回 0,否则走到下面,调用了一个
getInfo
函数。查看getInfo
函数,它的实现如下:
我们查看
getFieldAt
的实现
这里拿到
Description
,通过 Description
拿到 Fields
,而 Fields
里面包含了属性信息,既然拿到了 Fields
,就可以拿到属性相关的信息了。
2.小结
Mirror通过实例对象的meatadata
,在其内部创建了一个结构,用于输出metadata
中的descriptor
,在descriptor
中找到name
和numFields
,通过FieldDescriptor
中的fields
,来找到对当前属性的描述,然后通过指针移动,获取其他属性
- swfit进阶-11-swift中的Mirror的原理
- Flutter学习 - Bloc - 06 列表刷新与加载
- Flutter学习-GetX-03 状态管理
- Swift中MVVM对于列表中Cell的拆分(上)
- Flutter中Plugin的创建与发布 (超详细教程)
- Flutter学习-GetX-06 主题与本地化
- Flutter学习-GetX-01 路由管理
- Flutter中多module集成
- Swift中MVVM对于列表中Cell的拆分(下)
- Flutter学习-GetX-02 导航操作
- Flutter中Plugin开发之私有库和本地库
- Flutter学习 - Bloc - 01 初识Bloc
- Flutter Module 添加到iOS项目
- Flutter学习-GetX-05 生命周期
- Flutter学习-GetX-04 依赖注入
- ios Xib 使用技巧
- 底层原理-26-Block(上)
- Flutter学习之刷新组件-pull_to_refresh
- Flutter学习之原生通信BasicMessageChannel
- flutter学习之嵌入原生View - android