Swift笔记31:Swift标准库源码

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具体的实现。


2024-11-22 .png

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结构

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)
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容