Swift之深入解析反射Mirror的底层原理

Posted Forever_wj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swift之深入解析反射Mirror的底层原理相关的知识,希望对你有一定的参考价值。

一、Mirror 的底层分析

① 反射 API
  • 反射 API 由两部分实现:
    • 一部分是通过 Swift 实现,即 ReflectionMirror.swift;
    • 一部分是通过 C++ 实现,即 ReflectionMirror.mm;
  • 两者之间是通过暴露给 Swift 的 C++ 函数进行通信,即 @_silgen_name 修饰符会通知 Swift 编译器将这个 Swift 函数映射成 C++ 函数的符号;
  • 使用 @_silgen_name 关键字声明的方法,实际调用是括号中的方法,例如 swift_ydw_add 实际调用的是 c 中的 ydw_add;
  • 通过 C 定义一个方法,在 Swift 中使用:
	// 定义c方法
	// .h声明
	int ydw_add(int a, int b);
	// .c中实现
	int ydw_add(int a, int b){
	    return a+b;
	}
	
	// 桥接文件中引入头文件
	#import "test.h"
	
	// swift 使用
	var value = ydw_add(10, 20)
	print(value)
	
	// 打印结果
	30
  • 可以将上述代码中的“桥接文件中引入头文件”更改为采用 @_silgen_name 关键字的方式:
	// swift中针对ydw_add方法的声明
	// 通过@_silgen_name声明
	@_silgen_name("ydw_add")
	func swift_ydw_add(_ a: Int32, _ b: Int32) -> Int32
	
	// 使用
	var value = swift_cjl_add(20, 30)
	print(value)
	
	// 打印结果
	50
② Mirror
  • Mirror 的源码是在 Mirror.swift 文件中,路径为 swift->stdlib->public->core->Mirror.swift。
  • 在 Mirror.swift 文件中找到 Mirror,可以看到它是一个结构体类型:
	public struct Mirror {
	  /// Representation of descendant classes that don't override
	  /// `customMirror`.
	  ///
	  /// Note that the effect of this setting goes no deeper than the
	  /// nearest descendant class that overrides `customMirror`, which
	  /// in turn can determine representation of *its* descendants.
	  internal enum _DefaultDescendantRepresentation {
	    /// Generate a default mirror for descendant classes that don't
	    /// override `customMirror`.
	    ///
	    /// This case is the default.
	    case generated
	
	    /// Suppress the representation of descendant classes that don't
	    /// override `customMirror`.
	    ///
	    /// This option may be useful at the root of a class cluster, where
	    /// implementation details of descendants should generally not be
	    /// visible to clients.
	    case suppressed
	  }
  • 查找其初始化方法 public init(reflecting subject: Any):
	public init(reflecting subject: Any) {
	    // 判断 subject 是否符合 CustomReflectable 动态类型
	    if case let customized as CustomReflectable = subject {
	      // 如果符合,则由 customMirror 确定属性
	      self = customized.customMirror
	    } else {
	      // 如果不符合,则由语言生成
	      self = Mirror(internalReflecting: subject)
	    }
	}
  • 查找 internalReflecting 方法(路径为 swift->stdlib->public->core->ReflectionMirror.swift),如下:
	extension Mirror {
	  // Mirror的初始化器中检索需要的信息
	  /*
	  - subject 将要被反射的值 
	  - subjectType 将要被反射的 subject 值的类型,通常是值的运行时类型
	  */ 
	  internal init(internalReflecting subject: Any,
	              subjectType: Any.Type? = nil,
	              customAncestor: Mirror? = nil)
	  {
	    // 根据_getNormalizedType获取传入的subject的真正类型,其中type(of: subject)获取的动态类型
	    let subjectType = subjectType ?? _getNormalizedType(subject, type: type(of: subject))
	    // 获取属性大小
	    let childCount = _getChildCount(subject, type: subjectType)
	    // 遍历,将属性存储到字典中
	    let children = (0 ..< childCount).lazy.map({
	      // getChild函数时C++的_getChild 函数的简单封装,将标签名字中包含的C字符串转换为Swift字符串
	      getChild(of: subject, type: subjectType, index: $0)
	    })
	    // 赋值给Mirror的属性children
	    self.children = Children(children)
	    // 设置父类反射
	    self._makeSuperclassMirror = { // 按需求构建父类的Mirror的闭包
	      // 获取传入对象的类
	      guard let subjectClass = subjectType as? AnyClass,
	            // 获取父类
	            let superclass = _getSuperclass(subjectClass) else {
	        return nil // 非类的类型、没有父类的类的Mirror,会获取到nil
	      }
	      // 调用者可以用一个可作为父类的Mirror直接返回Mirror实例来指定自定义的祖先的表现
	      // Handle custom ancestors. If we've hit the custom ancestor's subject type,
	      // or descendants are suppressed, return it. Otherwise continue reflecting.
	      if let customAncestor = customAncestor {
	        if superclass == customAncestor.subjectType {
	          return customAncestor
	        }
	        if customAncestor._defaultDescendantRepresentation == .suppressed {
	          return customAncestor
	        }
	      }
	      // 给相同值返回一个将 superclass作为 subjectType的新的Mirror
	      return Mirror(internalReflecting: subject,
	                    subjectType: superclass,
	                    customAncestor: customAncestor)
	    }
	
	    // 获取并解析显示的样式,并设置Mirror的其他属性
	    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
	  }
	  // 快速查找
	  internal static func quickLookObject(_ subject: Any) -> _PlaygroundQuickLook? {
	#if _runtime(_ObjC)
	    let object = _getQuickLookObject(subject)
	    return object.flatMap(_getClassPlaygroundQuickLook)
	#else
	    return nil
	#endif
	  }
	}
	

	// superclassMirror属性的底层返回
	public var superclassMirror: Mirror? {
	    return _makeSuperclassMirror()
	}
	nternal let _makeSuperclassMirror: () -> Mirror?
  • internalReflecting 的流程分析:
    • 通过 _getNormalizedType 获取传入的 subject 的真正类型;
    • 通过 _getChildCount 方法获取类中的属性个数;
    • 遍历属性,通过 getChild 方法(C++ 的 _getChild 函数的简单封装)将标签名字中包含的 C 字符串转换为 Swift 字符串,并将属性存储到字典中,赋值给 Mirror 的属性 children;
    • Mirror 有一个属性 superclassMirror,会返回该类的父类,其底层是返回一个 _makeSuperclassMirror 属性,用于保存父类的 Mirror 闭包。首先会通过 subjectType 获取父类,然后按照需求构建父类的 Mirror 闭包,如果是非类的类型、没有父类的类的 Mirror,会获取到 nil。反之,则直接返回一个可作为父类的 Mirror 的实例对象。
    • 获取并解析显示的样式,并设置 Mirror 的其它属性。
  • 进入 _getNormalizedType 的实现,根据定义,最终会调用 C++ 中的 swift_reflectionMirror_normalizedType -> Call 方法:
	@_silgen_name("swift_reflectionMirror_normalizedType")
	internal 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; });
	}
 
	/*
	- passedValue 实际需要传入的swift的值的指针
	- T 该值的静态类型
	- passedType 被显式传入且会用在反射过程中的类型
	- f 传递被查找到的会被调用的实现的对象引用
	- 返回值:返回f参数调用时的返回值
	*/ 
	template<typename F>
	auto call(OpaqueValue *passedValue, const Metadata *T, const Metadata *passedType,
	          const F &f) -> decltype(f(nullptr))
	{
	  // 获取type
	  const Metadata *type;
	  OpaqueValue *value;
	  std::tie(type, value) = unwrapExistential(T, passedValue);
	  // 判断传入type是否为空,如果不为空,则直接赋值给type
	  if (passedType != nullptr) {
	    type = passedType;
	  }
	  // 使用 ReflectionMirrorImpl 子类的实例去结束调用f,然后会调用这个实例上的方法去真正的工作完成
	  auto call = [&](ReflectionMirrorImpl *impl) {
	    // 返回的type是传入非type
	    impl->type = type;
	    impl->value = value;
	    auto result = f(impl);
	    return result;
	  };
	  
	  .....
	  
	  switch (type->getKind()) {
	    case MetadataKind::Tuple: { // 元组
	        ......
	    }
	    case MetadataKind::Struct: { // 结构体
	       ......
	    }
	    case MetadataKind::Enum:   // 枚举
	    case MetadataKind::Optional: { // 可选
	     ......
	    }
	    
	    ......
	}
	
	// unwrapExistential实现
	static std::tuple<const Metadata *, OpaqueValue *>
	unwrapExistential(const Metadata *T, OpaqueValue *Value) {
	  // If the value is an existential container, look through it to reflect the
	  // contained value.如果该值是一个存在的容器,请查看它以反映包含的值。
	  // TODO: Should look through existential metatypes too, but it doesn't
	  // really matter yet since we don't have any special mirror behavior for
	  // concrete metatypes yet.
	  while (T->getKind() == MetadataKind::Existential) {
	    auto *existential
	      = static_cast<const ExistentialTypeMetadata *>(T);
	
	    // Unwrap the existential container.打开存在容器
	    T = existential->getDynamicType(Value);
	    Value = existential->projectValue(Value);
	
	    // Existential containers can end up nested in some cases due to generic
	    // abstraction barriers.  Repeat in case we have a nested existential.
	  }
	  return std::make_tuple(T, Value);
	}
	

	// getDynamicType的实现
	template<> const Metadata *
	ExistentialTypeMetadata::getDynamicType(const OpaqueValue *container) const {
	// 根据 获取此存在类型使用的表示形式 判断
	  switch (getRepresentation()) {
	  case ExistentialTypeRepresentation::Class: {
	    auto classContainer =
	      reinterpret_cast<const ClassExistentialContainer*>(container);
	    void *obj = classContainer->Value;
	    return swift_getObjectType(reinterpret_cast<HeapObject*>(obj));
	  }
	  case ExistentialTypeRepresentation::Opaque: {
	    auto opaqueContainer =
	      reinterpret_cast<const OpaqueExistentialContainer*>(container);
	    return opaqueContainer->Type;
	  }
	  case ExistentialTypeRepresentation::Error: {
	    const SwiftError *errorBox
	      = *reinterpret_cast<const SwiftError * const *>(container);
	    return errorBox->getType();
	  }
	  }
	
	  swift_runtime_unreachable(
	      "Unhandled ExistentialTypeRepresentation in switch.");
	}
  • call 中主要是一个 switch 声明和一些额外的逻辑去处理特殊的情况,主要是 ReflectionMirrorImpl 的子类实例去结束调用 f,然后会调用这个实例上的方法去让真正的工作完成。
  • _getNormalizedType 的主要流程分析:
    • 首先根据 unwrapExistential 获取 type 类型,其依赖于 metaData 元数据;
    • 判断传入的 passedType 是否为空,如果不为空,则直接赋值给 type;
    • 使用 ReflectionMirrorImpl 子类的实例去结束调用 f,然后会调用这个实例上的方法完成。
③ _getNormalizedType
  • 运行 swift 源码,在 Call 函数的第一行加断点;
  • 在源码终端依次输入下面代码:
	class YDWTeacher {
		var age = 18
	}
	var t = YDWTeacher()
	let mirror = Mirror(reflecting: t)
  • 程序会执行在 Call 的调用处,运行结果如下:

在这里插入图片描述

  • 其中参数的调试结果说明:
    • value 是 Mirror 实例;
    • type 是 type(of:) 获取的类型;
    • T 是自己传入的类型;

在这里插入图片描述

④ ReflectionMirrorImpl 反射基类
  • ReflectionMirrorImpl 的种类如下:
    • TupleImpl 元组的反射;
    • StructImpl 结构体的反射;
    • EnumImpl 枚举的反射;
    • ClassImpl 类的反射;
    • MetatypeImpl 元数据的反射;
    • OpaqueImpl 不透明类型的反射;
  • 以 Struct 的反射为例,首先查看 ReflectionMirrorImpl 的底层定义:
	// Abstract base class for reflection implementations.
	struct ReflectionMirrorImpl {
	  const Metadata *type;
	  OpaqueValue *value;
	  
	  // 显示的样式
	  virtual char displayStyle() = 0;
	  // 属性个数
	  virtual intptr_t count() = 0;
	  // 获取偏移值
	  virtual intptr_t childOffset(intptr_t index) = 0;
	  // 获取元数据
	  virtual const FieldType childMetadata(intptr_t index,
	                                        const char **outName,
	                                        void (**outFreeFunc)(const char *)) = 0;
	  //获取属性
	  virtual AnyReturn subscript(intptr_t index, const char **outName,
	                              void (**outFreeFunc)(const char *)) = 0;
	  //获取枚举的case名字
	  virtual const char *enumCaseName() { return nullptr; }
	
	#if SWIFT_OBJC_INTEROP
	// 快速查找
	  virtual id quickLookObject() { return nil; }
	#endif
	  
	  // For class types, traverse through superclasses when providing field
	  // information. The base implementations call through to their local-only
	  // counterparts.
	  // 递归查找父类的属性
	  virtual intptr_t recursiveCount() {
	    return count();
	  }
	  // 递归查找父类属性的偏移值
	  virtual intptr_t recursiveChildOffset(intptr_t index) {
	    return childOffset(index);
	  }
	  // 递归获取父类的元数据
	  virtual const FieldType recursiveChildMetadata(intptr_t index,
	                                                 const char **outName,
	                                                 void (**outFreeFunc)(const char *))
	  {
	    return childMetadata(index, outName, outFreeFunc);
	  }
	// 析构函数
	  virtual ~ReflectionMirrorImpl() {}
	};
  • 继续进入 StructImpl 结构体的底层实现:
	// Implementation for structs.
	// ReflectionMirrorImpl 的子类 StructImpl 结构体反射
	struct StructImpl : ReflectionMirrorImpl {
	  bool isReflectable() { // 是否支持反射
	    const auto *Struct = static_cast<const StructMetadata *>(type);
	    const auto &Description = Struct->getDescription();
	    return Description->isReflectable();
	  }
	  // 用 s 的显式样式来表明这是一个结构体
	  char displayStyle() {
	    return 's';
	  }
	  
	  intptr_t count() {
	    if (!isReflectable()) {
	      return 0;
	    }
	// 首先也是找到metadata,然后通过metadata找到desc,然后找到fields,即 NumFields 记录属性的count
	    auto *Struct = static_cast<const StructMetadata *>(type);
	    return Struct->getDescription()->NumFields;// 属性的count
	  }
	
	  intptr_t childOffset(intptr_t i) {
	    auto *Struct = static_cast<const StructMetadata *>(type);
	    // 边界检查
	    if (i < 0 || (size_t)i > Struct->getDescription()->NumFields)
	      swift::crash("Swift mirror subscript bounds check failure");
	
	    // Load the offset from its respective vector.
	    // 获取偏移值
	    return Struct->getFieldOffsets()[i];
	  }
	
	  const FieldType childMetadata(intptr_t i, const char **outName,
	                                void (**outFreeFunc)(const char *)) {
	    StringRef name;
	    FieldType fieldInfo;
	    // 通过getFieldAt获取属性的名称
	    std::tie(name, fieldInfo) = getFieldAt(type, i);
	    assert(!fieldInfo.isIndirect() && "indirect struct fields not implemented");
	    
	    *outName = name.data();
	    *outFreeFunc = nullptr;
	    
	    return fieldInfo;
	  }
	  // subscript 用来获取当前属性的名称和值
	  AnyReturn subscript(intptr_t i, const char **outName,
	                      void (**outFreeFunc)(const char *)) {
	    // 获取metaadata
	    auto fieldInfo = childMetadata(i, outName, outFreeFunc);
	
	    auto *bytes = reinterpret_cast<char*>(value);
	    // 获取属性的偏移值
	    auto fieldOffset = childOffset(i);
	    // 计算字段存储的指针
	    auto *fieldData = reinterpret_cast<OpaqueValue *>(bytes + fieldOffset);
	
	    return copyFieldContents(fieldData, fieldInfo);
	  }
	};
  • 注意点:
    • count 方法中属性个数的获取,是通过 metadata,然后找到其 desc,然后找到 NumFields 获取的,即 NumFields 记录属性的 count;
    • subscript 方法主要用来获取当前属性的名称和值;
      • 首先获取 metadata;
      • 然后获取属性的偏移值 fieldOffset;
      • 通过首地址+偏移值,计算属性存储的指针。

二、仿写 Mirror

① TargetStructMetadata 结构体:struct 反射类
  • 从 Struct 的反射类 StructImpl 中可以知道,其 type 的类型是 StructMetadata:
	// Implementation for structs.
	struct StructImpl : ReflectionMirrorImpl {
	  bool isReflectable() {
	    const auto *Struct = static_cast<const StructMetadata *>(type);
	    const auto &Description = Struct->getDescription();
	    return Description->isReflectable();
	  }
	char displayStyle() {
    	return 's';
    }
  
    intptr_t count() {
     if iOS开发-Swift进阶之Mirror源码解析!

Swift-进阶 07:Mirror源码解析

Swift之深入解析“泛型”的底层原理

Swift之深入解析内存管理的底层原理

Swift之深入解析协议Protocol的底层原理

Swift之深入解析可选类型Optional的底层原理