前言
SwiftGG的Mirror 的工作原理这篇文章描述了Mirror是如何工作的,参考该文中内容去解读具体的源码。
一、 Mirror初始化函数
struct Mirror {
public init(reflecting subject: Any) {
//if case, 实现了CustomReflectable协议的情况
if case let customized as CustomReflectable = subject {
self = customized.customMirror
} else {
//调用extension中的init
self = Mirror(internalReflecting: subject)
}
}
//反射实例结构的元素。label不为nil可表现为存储属性或enum的case;如果向descendant(_:_:)方法中传入strings,label被用于查找
public typealias Child = (label: String?, value: Any)
//用于表示子结构的类型。
public typealias Children = AnyCollection<Child>
//关于如何展示反射对象的策略
public enum DisplayStyle {
case `struct`, `class`, `enum`, tuple, optional, collection
case dictionary, `set`
}
//被反射subject的静太类型,当它是另一个mirror的superclassMirror时可能与subject的动态类型不同
public let subjectType: Any.Type
//描述反射subject结构的子元素集合
public let children: Children
//反射subject的建议显示类型
public let displayStyle: DisplayStyle?
//如果存在,则为对象的超类的反射
public var superclassMirror: Mirror? {
return _makeSuperclassMirror()
}
internal let _makeSuperclassMirror: () -> Mirror?
//不覆盖`customMirror`的派生类的表示形式。
internal let _defaultDescendantRepresentation: _DefaultDescendantRepresentation
}
extension Mirror {
internal init(internalReflecting subject: Any,
subjectType: Any.Type? = nil,
customAncestor: Mirror? = nil)
{
//传入的subject的类型,如果为nil,则调用_getNormalizedType
let subjectType = subjectType ?? _getNormalizedType(subject, type: type(of: subject))
//拿到subject的元素数量
let childCount = _getChildCount(subject, type: subjectType)
//创建获取子元素的延时集合
let children = (0 ..< childCount).lazy.map({
//swift_reflectionMirror_subscript, impl->subscript
getChild(of: subject, type: subjectType, index: $0)
})
//构建 children 对象
self.children = Children(children) //AnyCollection<Child>(children)
self._makeSuperclassMirror = {
guard let subjectClass = subjectType as? AnyClass,
let superclass = _getSuperclass(subjectClass) else {
return nil
}
// 处理传进来的customAncestor参数
if let customAncestor = customAncestor {
//超类为customAncestor.subjectType刚返回customAncestor
if superclass == customAncestor.subjectType {
return customAncestor
}
//customAncestor的派生类表征为suppressed,则返回customAncestor
if customAncestor._defaultDescendantRepresentation == .suppressed {
return customAncestor
}
}
//否则递归再次反射
return Mirror(internalReflecting: subject,
subjectType: superclass,
customAncestor: customAncestor)
}
//获得subject的展示类型,然后根据case设置self.displayStyle
let rawDisplayStyle = _getDisplayStyle(subject)
switch UnicodeScalar(Int(rawDisplayStyle)) {
case "c": self.displayStyle = .class
case "e": self.displayStyle = .enum
case "s": self.displayStyle = .struct
case "t": self.displayStyle = .tuple
case "\0": self.displayStyle = nil
default: preconditionFailure("Unknown raw display style '\(rawDisplayStyle)'")
}
self.subjectType = subjectType
self._defaultDescendantRepresentation = .generated
}
}
@_silgen_name
: 通知 Swift 编译器将这个函数映射成自定义符号SWIFT_CC(swift)
: 告诉编译器这个运行时函数使用Swift调用约定SWIFT_RUNTIME_STDLIB_INTERFACE
: extern “C” attribute((visibility(“default”))),告诉编译器按C(而不是C++)的方式进行编译
反射的 API 有一部分是在ReflectionMirror.swift
文件中用 Swift 实现的,另一部分是在ReflectionMirror.mm
中用 C++ 实现的。在 Swift 中访问 C++ 的类得有一个 C 的连接层,但这里通过@_silgen_name
将用到的函数在 Swift 中直接声明成指定的自定义符号,把对应名字的C++ 函数通过SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API
实现为可被 Swift 直接调用的方式。
理解了@_silgen_name, 那我们来看下_getNormalizedType
、_getChildCount
、_getDisplayStyle
对应的C++函数
//func _getNormalizedType<T>(_: T, type: Any.Type) -> Any.Type
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API
const Metadata *swift_reflectionMirror_normalizedType(OpaqueValue *value, const Metadata *type, const Metadata *T) {
return call(value, T, type, [](ReflectionMirrorImpl *impl) {
return impl->type; });
}
//func _getChildCount<T>(_: T, type: Any.Type) -> Int
SWIFT_CC(swift) SWIFT_RUNTIME_ST