Compatibility in Swift

360 阅读3分钟

作为一个对Swift历史不太了解的开发者,如何才能清晰的理解Swift中compatibility问题,比如

  • 什么是ABI 稳定
  • Swift编译器与Clang区别是啥
  • 啥是Swift编译器兼容模式

粗看了几篇文章,不甚理解,正好一次面试中被问到了,于是想记录一下

编译器(compiler)

  • 编译iOS程序的编译器是llvm
    • llvm是一个编译器和编译过程的项目,llvm不仅支持OC和Swift
    • 当然,编译不同的语言,需要用到不同的编译前端,编译前端是llvm的组成部分
    • OC对应的编译前端程序是clang
    • Swift对应的编译前端程序也叫Swift
  • 编译器或者说前面提到的编译器前端的作用是什么
    • 预处理代码,比如将macro, import, include展开
    • 校验我们写的程序是否存在语法错误,并进行相应的错误,警告提醒
  • Swift编译器(前端)版本是跟随Xcode的版本在更新的,且一个Xcode中只有一个Swift编译器

Swift编译器兼容模式(compatibility mode)

Swift 4之前,Swift编译器(前端)只能编译对应版本的Swift语言开发的程序,简言之,就是Swift 3的编译器只能用来编译Swift 3开发的程序,如果是Swift 2开发的程序,是无法用Swift 3编译器来编译的,原因在于Swift 3的编译器在进行语法检查时是根据Swift 3语法标准执行的,Swift 3与Swift 2之间语法不兼容

自Swift 4和Swift 4编译器开始,引入了兼容模式

  • 当选择使用兼容模式时,Swift编译器可以支持更早版本的Swift语法
  • 比如Swift 4的编译器仍然可以编译Swift 3.2的程序
  • 当然即使在兼容模式下,Swift 4的编译器仍然支持Swift 4的语法特性
  • 这一选项就是通过Xcode->build setting->Swift Language Version控制的

ABI稳定(ABI Stability)

ABI是Application Binary Interface的缩写,深入了解它确实需要汇编、操作系统等深入的知识储备。本文仅做简单描述

ABI顾名思义,应用程序二进制接口。可以和API对比着来理解,API是一个程序或SDK提供的一些函数、方法,ABI也是类似作用,只不过是更底层的函数,方法,协议或约定

ABI描述更底层的协议约定,比如我们程序中的对象如何在内存中申请空间,运行时系统包含哪些方法等,下面列出ABI包含的内容:

  • Data Layout
  • Type Metadata
  • Mangling
  • Calling Convention
  • Runtime
  • Standard Library

一个新的语言,除了要有基本的语法,还要有支持它运行的编译器和运行时等条件

所以,Swift 5之前,Swift的ABI一直不稳定,其中内容在不同的版本差异是比较大的

  • 那时,一个用Swift开发的程序,打包后是需要将ABI内容打包进这个App包中的
  • 也就是说,可能一个iPhone上,有多个App,每个App对应的Swift的ABI是不同的

自Swift 5开始,ABI则稳定了,由此带来的好处是

  • 就是说只要是Swift 5或之后版本的编译器编译打包出来的App,都是ABI稳定的
  • 所以也无需再将ABI程序、内容打包到App中,可以直接集成到iPhone的操作系统iOS中了,App的包体积会有明显的减少
  • 因为所有App都将使用同一个Swift运行时、standard library,所以内存占用和启动耗时上也会有优化
  • 官方给了一个例子,一个Swift 5编译器打包的App可以运行在Swift 5的运行时下,也可以运行在Swift 6的运行时环境下

参考