Swift在2015年正式开源,github地址:https://github.com/swiftlang/swift
几个可能经常看的目录
Docs : 一些文档 https://github.com/apple/swift/tree/main/docs
stdlib: Swift源码 ,标准库 https://github.com/apple/swift/tree/main/stdlib
lib: C++源码 https://github.com/apple/swift/tree/main/lib
include: C++头文件 https://github.com/apple/swift/tree/main/include
各种语言占比:C++ 49.2% , Swift 42.0% , C 5.2%
标准库源码的位置
我们常用的Int,Array,Dictionary等等常用类型都属于标准库。
//开发文档点进去看的只是声明,可以去源码中找实现。
stdlib -> public -> core 路径下,我们可以查看各种属性和方法的底层声明和实现。https://github.com/swiftlang/swift/blob/main/stdlib/public/core/
查看具体函数的实现
我们为了查看源码方便可以建一个macOS工程,只把core文件夹或者整个源码引用进工程。
比如我们想了解Array的map具体的实现。

flatMap/compactMap/reduce //搜索 func compactMap 去掉空的值,可选项绑定
SubString.Swift base找到之前的String appdend会创建新的String
Optional.Swift map 部位nil的话直接返回,不为nil解包值,然后包装可选项返回去,有可能双重可选项。 flatMap如果不是可选项,返回可选项,单层可选项
Metadata分析
在线文档:https://github.com/apple/swift/blob/main/docs/ABI/TypeMetadata.rst
本地文档:同样的我们把目录路径docs/ABI/TypeMetadata文件打开可以直接查看
堆对象前8字节指向Metadata,retaincount 8字节。 找到Metadata下移0x50后是虚表地址
结构体、协议、枚举、Swift Class、OC Class、可选项、元组、函数、Metatype等有不同的Metadata。
Metatype可以认为是Metatype的Metatype。
- Class metadata has of kind of 0、 •
- [Struct metadata](https://github.com/apple/swift/blob/main/docs/ABI/TypeMetadata.rst#struct-* metadata) has a kind of 1.
- Enum metadata has a kind of 2.
- Optional metadata has a kind of 3
- Opaque metadata has a kind of 8
- Tuple metadata has a kind of 9.
- Function metadata has a kind of 10.
- Protocol metadata has a kind of 12. This is used for protocol types, for protocol compositions, and for the Any type.
- Metatype metadata has a kind of 13. //可以认为是 Metadata的Metadata
- Objective C class wrapper metadata has a kind of 14.
- Existential metatype metadata has a kind of 15. //CFArray , CF开头的类
Class metadata结构
Class metadata
Offset指针偏移量,来存放不同的metadata数据
- Offset 0 存放 isapointer(kind),isa指针指向类的与objective -c兼容的元类记录,存储在偏移量0处,代替整数类型标识符。 kind targetMetadata
- Offset 1 superClass 指向超类元数据记录的超指针存储在偏移量1处。如果类是根类,则为空。
- Offset 2 和 Offset3 是保留给OCRuntime用的
- Offset 4 rodata pointer,
- Offset -2倒数第二个 ,析构函数指针存储在元数据指针的偏移量
metadata的应用
和OC中class_copyIvarList()运行时方式不同.
通过metadata 类信息可以查找成员属性、类型。
比如通过开源库KAKAJSON进行字典和model互转。核心就是获取元类数据,获取所有成员。
KAKAJSON : Metadata文件夹单独拿走,注意观察各种Type文件。可以实现 let type = Metadata.type(SCat<Double>.self) 里面存放的数据结构,类型是Class类型。
我们平时开发也可以用来调试打印类信息,可以观察到数据属性和它在内存中的字节偏移量。
如果是类的Metadata,layout的布局就是官方文档中描述的布局。isapointer-superClass-OCRuntime-rodata pointer等等
desciption :UnsafeMutablePointer<ClassDescriptor> 描述器,描述器里面有个FIeldOffsetPoiner<Int> 找到属性
Swift 的类继承NSObject元数据的区别
class Cat: NSObject{
var age = 3
}
如果class Cat 继承NSObject ,元数据结构发生变化,age偏移从16变为8。因为已经从swift类变成OC类了。类型从Class变为了objCClassWarpper。OC对象前8字节是isa,所以偏移变成8。
反射
对于任意一个类型,都能够动态获取这个类的所有属性和方法信息。
对于任意一个实例,都能够动态调用它的任意方法和属性。
反射是编程语言中一项强大的能力。比如Java语言的反射机制,OC的Runtime
Swift的反射机制目前比较弱,通过Mirror 类型来提供简单的反射功能。
struct Person {
var age: Int = 0
var name: String = ""
}
class MirrorViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
execMirror()
}
func execMirror() {
let mirror = Mirror(reflecting: Person(age: 18, name: "jack"))
print(mirror.displayStyle!) // struct
print(mirror.subjectType) // Person
print(mirror.superclassMirror as Any) // nil ,结构体没有父类
for case let (label?, value) in mirror.children {
// age 18
// name jack
print(label, value)
}
}
}