struct GitArtOS {
var age = 18
var name = "FGH"
var subclassName = "二年级"
}
struct GitArtOSMetadata {
var kind: Int
var description: UnsafeMutablePointer<GitArtOSMetadataDesc>
}
struct GitArtOSMetadataDesc {
var flags: UInt32
var parent: UInt32 // 展示用Uint32代替,实际是相同大小的结构体,
var name: GitArtOSDirectPointer<CChar>
// . . . (当前研究获取属性类型,后面的属性先不管)
var accessFunctionPtr: GitArtOSDirectPointer<UnsafeRawPointer> // 不在乎具体类型,就先用UnsafeRawPointer
var fields: GitArtOSDirectPointer<GitArtOSFieldDescription> // 不在乎具体类型,就先用UnsafeRawPointer
var numFields: UInt32 // 属性个数
var fieldOffsetVectorOffset: UInt32
}
struct GitArtOSDirectPointer<T>{
var offset: Int32
// 偏移offset位置,获取内容指针
mutating func get() -> UnsafeMutablePointer<T> {
let offset = self.offset
// withUnsafePointer获取指针
return withUnsafePointer(to: &self) { p in
// UnsafeMutablePointer 返回T类型对象的指针
// UnsafeRawPointer将p指针转换为未知类型
// numericCast将offset转换为偏移单位数
// advanced进行内存偏移
// assumingMemoryBound绑定指针为T类型
return UnsafeMutablePointer(mutating: UnsafeRawPointer(p).advanced(by: numericCast(offset)).assumingMemoryBound(to: T.self))
}
}
}
// 记录结构体内所有属性的结构
struct GitArtOSFieldDescription {
var MangledTypeName: GitArtOSDirectPointer<CChar>
var Superclass: GitArtOSDirectPointer<CChar>
var Kind: UInt16
var FieldRecordSize: UInt16
var NumFields: UInt32
var fgfields: GitArtOSFieldRecord // 连续存储空间 (有几个数据,就会在后面添加几个记录,通过内存平移读取)
}
// 每个属性的内容
struct GitArtOSFieldRecord {
var flag: Int32
var mangledTypeName: GitArtOSDirectPointer<CChar>
var fieldName: GitArtOSDirectPointer<CChar> // 属性名称
}
let gitartos = unsafeBitCast(GitArtOS.self as Any.Type, to: UnsafeMutablePointer<GitArtOSMetadata>.self)
let namePtr = gitartos.pointee.description.pointee.name.get()
print(String(cString:namePtr ))
//GitArtOS
let count = gitartos.pointee.description.pointee.numFields
print("GitArtOS属性个数:\(count)")
// 单独读取第一个属性名
var fields = gitartos.pointee.description.pointee.fields.get()
let fieldRecord1Name = fields.pointee.fgfields.fieldName.get()
print(String(cString: fieldRecord1Name))
// 读取所有记录
print("----读取所有属性名----")
(0..<count).forEach { index in
let recordPtr = withUnsafePointer(to: &fields.pointee.fgfields) {
return UnsafeMutablePointer(mutating: UnsafeRawPointer($0).assumingMemoryBound(to: GitArtOSFieldRecord.self).advanced(by: Int(index)))
}
print(String(cString: recordPtr.pointee.fieldName.get()))
}
print("--GitArtOS --dump----")
dump(GitArtOS()) // 相似的实现方式
打印结果:
GitArtOS
GitArtOS属性个数:3
age
----读取所有属性名----
age
name
subclassName
--GitArtOS --dump----
▿ __lldb_expr_22.GitArtOS
- age: 18
- name: "FGH"
- subclassName: "二年级"
Mirror
可以动态获取类型、成员变量,在运行时可以调用方法、属性等行为的特性.
-
Mirror.swift
文件 -
初始化方法
public init(reflecting subject: Any)
和 获取属性个数_getChildCount
-
类型获取 搜索
_getNormalizedType:
- 分析结构:
structMetadata
和RelativeDirectPointer
网友评论