C++、Java、Objective-C、Swift 二进制兼容测试

阿里云云栖社区 · · 1104 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

鉴于目前动态库在iOS App中使用越来越广泛,二进制的兼容问题可能会成为一个令人头疼的问题。本文主要对比一下C++、Java、Objecive-C和Swift的二进制兼容问题。

iOS端动态库使用情况

iOS 8开始支持App使用动态库。

苹果对提交的App的__TEXT__段大小是有限制的,很多巨无霸App容易超出这个限制。iOS9之前每个架构的__TEXT__段比较小,iOS9放大到了500MB。详细情况请看:To submit an app for review

开源库只能通过Podfile做源码引入,源码依赖,编译非常慢。

可持续构建也需要基于苹果的环境,比如使用Mac Pro/Mac Mini构建。Mac Pro比较昂贵,Mac mini性能不行,构建一次需要花费大量时间。

大型App为了加快编译速度,可以维护自己的私有仓库,把依赖的库尽量编译成Framework,加快编译速度。

Swift目前必须基于动态库开发。

基于动态库构建App,升级一个动态库需要将整个依赖树编译一遍。尤其是一些频繁变动的基础组件,比如视觉组件的改动,牵一发而动全身。

测试环境

C++、Java、OC和Swift分别实现Foo这个基类,然后再实现Bar这个子类,main则使用Bar类打印成员变量的信息。给Foo类添加成员变量member0,重新编译Foo(make foo && ./main),Bar和main不变,然后观察执行结果。

代码地址:binary_compatibility_test

LLDB一点有用的调试技巧。更多的调试功能,请参看:The LLDB Debugger


测试结果

1.C++会出现错位,但是没有崩溃。二进制也是比较脆弱的。

2.Java能正常工作。

3.OC能正常工作。OC非常适合基于动态库的组件方式。

4.Swift构造Bar对象就会崩溃。现状让我们非常头疼。


结果分析

C++的设计没有考虑到二进制兼容的问题,所以兼容很一般。

Java的二进制兼容非常完美,对象成员改变,方法增删,都不会轻易导致二进制兼容问题。详细情况请参看:Chapter 13. Binary Compatibility

OC使用方法和属性都使用消息派发,增加和删除方法,移动方法的顺序,都不会导致问题;另外对成员变量的改变做了支持,所以二进制兼容完美。

作为一种崭新的语言,Swift的二进制兼容最差,匪夷所思啊。

另外大家讨论的时候也提到C++虚函数改变顺序会不会出问题。针对这个问题我验证了一下,确认C++虚函数表里面函数的顺序完全取决于函数在头文件中声明的顺序。

比如Foo有func1和func2两个虚函数,调换func1和func2的顺序,不重新编译main。在main里面调用func2,实际上会调用到func1。



参考文章

1.C++ ABI Compliance Checker

2.Objective-C类成员变量深度剖析

3.Non Fragile ivars

4.Objc源码

5.Swift库二进制接口(ABI)兼容性研究

最后的最后:

Golang也是一门崭新的语言,我非常好奇它对二进制兼容这块是怎么考虑的,所以欢迎广大有为青年补充一个Golang版本。


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:阿里云云栖社区

查看原文:C++、Java、Objective-C、Swift 二进制兼容测试

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1104 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传