Swift版本都到5了,ABI稳定了,你清楚吗
一、ABl是什么
每个操作系统都会为运行在该系统下的应用程序提供应用程序二进制接口(Application Binary Interface,即ABI), 描述了应用程序和操作系统之间的底层接口,一个应用和它的库之间的底层接口。与API
不同的是:ABI允许编译好的目标代码在使用兼容ABI的系统中无需改动就能运行,而API则是定义 源代码
和 库
之间的接口,同样的代码可以在支持这个API的任何系统中编译。
ABI包含了应用程序在这个系统下运行时必须遵守的编程约定。ABI总是包含一系列的系统调用和使用这些系统调用的方法,以及关于程序可以使用的内存地址和使用机器寄存器的规定。从一个应用程序的角度看,ABI既是系统架构的一部分也是硬件体系结构的重点,因此只要违反二者之一的条件约束就会导致程序出现严重错误。
在 iOS
和 macOS
平台,Swift编写的二进制程序在运行时通过ABI与其他程序库或组件进行交互。程序的编译会产生一个或者多个二进制实体,这些二进制实体必须在一些很底层的细节上达成一致,才能被链接在一起执行。可以说ABI
就是一个规范,一种协议
。它会规定如何调用函数,如何在内存中表示数据,甚至是如何存储和访问metadata
。ABI底层包装的是具体平台硬件相关的程序代码了。
ABI涵盖了各种细节,如:
数据类型的大小、布局和对齐;
调用约定(控制着函数的参数如何传送以及如何接受返回值),例如,是所有的参数都通过栈传递,还是部分参数通过寄存器传递;哪个寄存器用于哪个函数参数;通过栈传递的第一个函数参数是最先push到栈上还是最后;
系统调用的编码和一个应用如何向操作系统进行系统调用;
以及在一个完整的操作系统ABI中,目标文件的二进制格式、程序库等等。
ABI稳不稳定与Swift版本是无关的,取决于swift的编译器版本。Xcode10.2集成了swift5.0编译器,只要使用这个版本以上的编译器,编译出来的二进制就是ABI稳定的。Swift5.0编译器提供了Swift4的语法兼容,也就是说即使你的项目代码仍然是swift4,编译出来的二进制也是ABI稳定的。
二、ABI稳定的利弊
ABI稳定是指把ABI锁定在某种形式,以至于未来的编译器都可以生成遵从这种形式的二进制实体(可以是程序库,也可以是应用程序)。ABI稳定之后,OS发行商就可以把Swift标准库和运行时作为操作系统的一部分嵌入。也就是说Apple 会把Swift runtime 放到 iOS 和 macOS 系统里,我们的swift App包里就不需要包含应用使用的标准库 和Swift runtime 拷贝了。同时在运行的时候,只要是用 Swift 5 (或以上) 的编译器编译出来的 binary,就可以跑在任意的 Swift 5 (或以上) 的 runtime 上。
Apple 通过 App Thinning 帮我们完成的,不需要开发者操心。在提交 app 时,Apple 将会按照 iOS 系统创建不同的下载包。对于 iOS 12.2 的系统,因为它们预装了 Swift 5 的 runtime,所以不再需要 Swift 的库,它们会被从 app bundle 中删掉。对于 iOS 12.2 以下的系统,外甥打灯笼,照旧。
一个新创建的空 app,针对 iOS 12.2 打包出来压缩后的下载大小是 26KB,而对 iOS 12.0 则是 2.4MB。如果你使用了很多标准库里的东西,那这个差距会更大 (因为没有用到的标准库的符号会被 strip 掉),对于一个比较有规模的 app 来说,一般可以减小 10M 左右的体积。
ABI稳定带来了以下好处:
大量减小app体积
针对已经嵌入swift runtime的系统(macOS 10.14.4, iOS 12.2, tvOS12.2, watchOS5.2),所有app使用同一个运行时, app启动不需要额外加载Swift runtime,在新系统上会更快更节省内存
Apple工程师可以在系统框架中使用Swift了
系统中统一使用了稳定的ABI之后,受益最大的应该就是Apple本身了。他们可以编写纯Swift系统框架了,不需要包一遍OC,代码运行效率会更高,维护成本也更低。
当然ABI稳定也有其弊端,因为 Swift runtime 现在被放到 iOS 系统里了,所以想要升级就没那么容易了。集成到OS的Swift runtime只能伴随iOS系统更新才会更新,不像稳定之前我们自己打包的会随着App更新而更新.
在 ABI 稳定之前,Swift runtime 是作为开发工具的一部分,被作为库打包到 app 中的。这样一来,在开发时,我们可以随意使用新版本 Swift 的类型或特性,因为它们的版本是开发者自己决定的。不过,当 ABI 稳定后,Swift runtime 变为了用户系统的一部分,它从开发工具,变为了运行的环境,不再由我们开发者唯一决定。比如说,对应 iOS 13 的 Swift 6 的标准库中添加了某个类型 A
,但是在 iOS 12.2 这个只搭载了 Swift 5 的系统中,并没有这个类型。这意味着我们需要在使用 Swift 的时候考虑设备兼容的问题:如果你需要兼容那些搭载了旧版本 Swift 的系统,那你将无法在代码里使用新版本的 Swift runtime 特性。
这和我们一直以来适配新系统的 API 时候的情况差不多,在 Swift 5 以后,我们需要等到 deploy target 升级到对应的版本,才能开始使用对应的 Swift 特性。这意味着,我们可能会需要写一些这样的兼容代码,类似我们熟悉的远程推送的注册这种版本判断:
// 假如 Swift 6.0 是 iOS 13.0 的 Swift 版本
- if #available(iOS 13.0, *) {
- // Swift 6.0 标准库中存在 A
- let a = A()
- } else {
- // 不存在 A 时的处理
- }
对于“新添加的某个类型”这种程度的兼容,我们可以用上面的方式处理。但是对于更靠近语言层面的一些东西 (比如现在已有的
Codable
这样的特性),恐怕适配起来就没有那么简单了。在未来,Deployment target 可能会和 Swift 语言版本挂钩,新的语言特性出现后,我们可能需要等待一段时间才能实际用上。而除了那些纯编译期间的内容外,任何与 Swift runtime 有关的特性,都会要遵守这个规则。三、ABI稳定的意义
对ABI做的每一个决定都会对编程语言产生长远的影响,甚至会制约一门编程语言在未来可以发展和进化的空间。Swift未来的版本可能会在更多垂直领域为ABI添加特性,但只要声明了某个平台的ABI已稳定,那么任何在效率以及灵活性上曾经不妥的设计都将永远伴着这个平台存在。
一旦ABI稳定了,就意味着它会伴着这个平台的一生一世,直至日益增长的依赖关系让它走向灭亡。
swift已经经历了五大版本,才声明ABI稳定的一个主要目的,就是为程序库的进化保留足够的灵活性,而不希望开发者由于ABI的稳定性而限制设计空间。
ABI与API的区别
应用程序接口(Application Programming Interface,API),又称为应用编程接口,就是软件系统不同组成部分衔接的约定。由于近年来软件的规模日益庞大,常常需要把复杂的系统划分成小的组成部分,编程接口的设计十分重要。程序设计的实践中,编程接口的设计首先要使软件系统的职责得到合理划分。良好的接口设计可以降低系统各部分的相互依赖,提高组成单元的内聚性,降低组成单元间的耦合程度,从而提高系统的维护性和扩展性。
ABI不同于API ,API定义了源代码和库之间的接口,因此同样的代码可以在支持这个API的任何系统中编译 ,然而ABI允许编译好的目标代码在使用兼容ABI的系统中无需改动就能运行。 ABI掩盖了各种细节,例如:调用约定控制着函数的参数如何传送以及如何接受返回值;系统调用的编码和一个应用如何向操作系统进行系统调用;以及在一个完整的操作系统ABI中,对象文件的二进制格式、程序库等等。一个完整的ABI,像 Intel二进制兼容标准 (iBCS) ,允许支持它的操作系统上的程序不经修改在其他支持此ABI的操作系统上运行。其他的 ABI 标准化细节包括C++ name decoration和同一个平台上的编译器之间的调用约定,但是不包括跨平台的兼容性。
一套完整的ABI(比如:Intel Binary Compatibility Standard (iBCS)),可以让程序在所有支持该ABI的系统上运行,而无需对程序进行修改。
Swift版本都到5了,ABI稳定了,你清楚吗相关推荐
- ABI稳定对于Swift意味着什么?
早在2018年9月,Apple公司的Swift 开发团队在官网更新了 "Swift 5.0 Release Process" ,主要介绍 Swift 5.0 的开发目标.发布流程和 ...
- 什么是ABI? Swift ABI稳定有什么用?
一.ABl是什么 每个操作系统都会为运行在该系统下的应用程序提供应用程序二进制接口(Application Binary Interface,即ABI), 描述了应用程序和操作系统之间的底层接口,一个 ...
- MacOS Xcode与Swift版本对应关系
Swift4 Xcode9.0 or later macOS 10.12.6+ Xcode 9.4.1 macOS 10.13.2+ ...
- swift 3迁移到swift5 swift版本迁移指南
Swift 5已经发布下面是官方swift5的介绍. Introducing Swift 5.1 Swift 5.1 now makes it easier to create and share b ...
- 电脑安装两个jdk版本无法切换 同时安装JDK8和JDK16 配置JAVA_HOME为JDK8但 java 和 javac 版本都是16
JDK8是目前最稳定使用最多的版本,大厂开发都使用JDK8.JDK16是目前最新版. 问题描述 同一台电脑同时安装了JDK8和JDK16,先安装了JDK16后安装的JDK8,设置JAVA_HOME指定 ...
- core image几个滤镜例子 oc版本和swift版本
oc版本 //万花筒模式 + (CGImageRef) getKaleidoscope:(CIContext *)context {CIImage * image =[CIImage imageWit ...
- [androd] android的在线源码网站,各个版本都有(目前已到俺android 4.2,但不包含kernel部分的代码)
android的在线源码阅读网站,各个版本都有(目前最新版本已到android 4.2,但不包含kernel部分的代码) 这个网站最大的特点是:可以在网页上方的搜索框,搜索整个网站所存储的源码中的字符 ...
- 使用swiftenv管理swift版本
swiftenv可以让你轻松安装和快速切换在多个版本之间切换的工具 安装swiftenv 1.下载swifenv git clone https://github.com/kylef/swiftenv ...
- ios使用SARUnArchiveANY 解压rar文件(oc和swift版本)
SARUnArchiveANY简介 开源库网址: https://github.com/saru2020/SARUnArchiveANY 简介: 一个iOS的非常有用的库来解压zip,.rar,7z文 ...
最新文章
- 3dContactPointAnnotationTool开发日志(二十)
- 修改图片src_【学习园地】企业SRC搭建
- android10获取imei,Android 10 root用户获取imei
- android 字符串替换_Android开发之旅:android架构
- 报告 | 2019程序员薪酬统计:软件开发比机器学习竟然更高?
- Java编程——输入某年某月某日,判断这一天是这一年的第几天?
- 苹果公布iPhone 12屏幕更换价格,果然没让人失望!
- 单片机点亮一个灯程序_初识单片机C语言编程,点亮第一个LED灯
- tocmat linux搭建测试环境,Apache+Tomcat 环境搭建(JK部署过程)
- jdk自带4种多线程创建方式
- Builder和Factory模式区别
- 创建oracle数据库job服务:PlSqlDev操作job
- js基础-8-浅拷贝和深拷贝
- 电源完整性之仿真设计原理
- linux中创建目录树,linux怎样创建目录树
- Rest请求使用Jackson反序列化报错,Cannot deserialize instance of `java.lang.String` out of START_OBJECT toke
- SQL零基础入门学习(九)
- 抖音同款雪花飘落圣诞树
- 桌面便利贴软件下载 电脑桌面便签小工具软件下载
- 如何添加Burp Suite添加https证书
热门文章
- php代码覆盖工具 -- PHPCodeCoverage
- IIS 异常 “System.OutOfMemoryException”、“存储空间不足,无法完成此操作。”
- 神经网络——异构卷积
- DBeaver连接MySql方法
- 在线点餐微信小程序插件 小程序一键接入肯德基麦当劳星巴克在线点餐
- 虎翼主机 mysql_Discuz!发论坛短消息提示mysql数据库错误
- linux查看防火墙开放了哪些端口,如何打开防火墙端口
- Python定义函数的三种形式
- 整体二分求区间第k大模板(POJ 2104)
- UI设计师都有哪些工作 网页设计规范包括什么