重学Swift第五篇:Mirror源码初探

本文主要探讨了Swift中的Mirror初始化函数,解释了@_silgen_name的作用,并揭示了如何通过C++函数与Swift交互实现反射。接着详细介绍了结构体的反射,特别是结构体元数据的获取,以及在反射过程中如何调用相应的方法来获取类型信息。
摘要由CSDN通过智能技术生成

前言

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值