Swift 4迁移总结:喜忧参半,新的起点

每日一篇优秀博文

这次Swift 3 到 4 的迁移代码要改动的地方比较少,花了一个下午的时间就完成了迁移。Swift 把原来 4.0 的目标从 ABI 稳定改为了源码兼容,此次代码的兼容性做的确实很好,这个目标算是达到了。然而对于一个成熟的项目而言,单纯语法上的兼容并不是全部,这次的升级也带来了一些新的变化。

3.2 和 4.0

在 3.0 的时候 swift 也提供了 2.3 和 3.0 两个版本,这次 4.0 也是提供了 3.2 版本。从我项目里的代码来看,从 3.0 到 3.2 要做的改动几乎没有,只是需要重新编译一次。社区的反应来看兼容 3.2 也没反馈出什么大的改动。所以对于推迟跟进 4.0 的团队来言会是一个很顺滑的过度,可以安心的切换到 Xcode 9。

为了让大家在迁移过程中更加顺利,swift 的 framework 支持 3.2 和 4.0 版本混编。如果你有好几个组件,可以单独为某个组件升级到 4.0 。这样大的团队可以不用一口气所有的代码都迁移到 4.0。
然而 3.2 和 4.0 的兼容并没有看上去那么美好。

首先是cocoapods的问题,反正在目前pods的framework只能指定一个版本的swift。issue在这里:Pods automatically compiling with Swift 4.0 in Xcode 9 beta 1。pod默认会使用一个swift版本编译全部,需要对不同的库单独指定swift版本。

遇到这个问题后,我把所有组件都迁移到了 4.0 ,app 因为有很多业务代码,希望先迁到 3.2 ,这样可以尽早支持 Xcode 9,同事可以尽早适配 iOS 11。然而。。。

Xcode 果然没让我失望啊,编译的时候没有错误提示只告诉你失败了:

compiling as Swift 3.2, with 'xxx' build as Swift 4.0(this is supported but may expose additional compiler issues)

提示也很清奇,我翻译一下:我们虽然支持混编,但是也可能混出毛病,所以你还是别混了。不过听闻丁香园的项目目前是主 app 4.0,组件 3.2 混编是成功的。所以说呢,如果要混可以碰碰运气。

顺便说下Xcode 9新的编译系统,我这里根本编译不过(可能因为我们混OC?),而且没有任何错误提示。苹果的软件质量果然是独领风骚,面向运气编程。

社区跟进及时

所以实际上,你要不然就全不动,停在 3.2。一旦要迁移就需要全部迁移到 4.0 。

好在这次因为语法改动小,我用到的大部分 Swift 库都支持了 4.0。弃更的只有 DOFavoriteButton ,一个点赞的控件。跟进比较慢的有 RxGesture、EZSwiftExtensions,不过已经也有了 4.0 的分支,也有人提了 4.0 的 PR,估计过几天应该也能合进去。只能说维护的人不够积极。
下面把我用到的 pod 贴出来:

  3.2 4.0
RxSwift/RxCocoa 4.0.0-beta.0
SnapKit 4.0.0
CryptoSwift 0.7.0 0.7.1
Alamofire 4.5.1 4.5.1兼容(5.0还未发布)
ObjectMapper 2.2.9 3.0
SwiftyAttributes 3.2.0 4.0.0
Kingfisher 4.1.0 4.0
MonkeyKing 1.4.0

通常情况下3.0是可以直接在3.2下编译的,所以“无”并不表示不能使用,指开发者没有单独声明一个版本兼容3.2。

4.0 开始与 OC 正式分道扬镳

为了照顾原有的开发者,Swift 2.0 的时候要做到的目标是与 OC 尽量兼容,除了几个基础的数据类型比如 Int、String 与OC不同外,其他的 API 都和 OC 保持一致,完全可以用 OC 的习惯写 Swift 。到 3.0 的时候Swift 体系开始独自进化,开始有自己的命名规范。

到 4.0 的时候,Xcode 用 Swift 重写了编译器,虽然 New build system 目前还在 preview,也确实有很多问题,然而针对 Swift 的编译优化又取得了不小的提升。我已经能感觉到苹果想要抛弃 OC 的意思,至少是非常明显的嫌弃的意思。

从代码层面来看,原先一个类只要是 NSObject 的子类,默认这个类的所有的属性方法都会自动添加给 OC 调用的 bridge,在 4.0 里这个功能被关闭了。这也是迁移 4.0 的一个比较大的工作量(对于和 OC 混编的项目)。什么意思呢,以前我们用 Swift 自定义了一个控件,原先在 OC 中引入 module 的头文件后,可以调用到这个控件公开的所有属性、方法。但是迁移到 4.0 后,所有属性、方法默认都是不能访问到,需要到控件里给要暴露给 OC 使用的属性方法前加上 @objc 。

这个改动影响非常深远。这等于是让开发者二选一了。如果我们用 Swift 写一个组件,需要支持 OC 加上 @objc 标志,编译时就要生成给 OC 调用的声明,这降低了一些些性能。但是不加的话 OC 又调用不到。更深的原因是,在写组件的时候我们并不确切的知道业务方是用 OC 还是 Swift 调用的。除非业务代码全是 Swift。或者只能全盘做 OC 桥接,到处都是 @objc,如果上面调用的是 Swift,这些又白加了。

这里还出现了另外一个细节。如果我们在 OC 里给 UIView 声明了一个属性 size,在 Swift 里也声明了一个属性 size。如果是在一个 framework 里,会编译失败提示冲突了。然而如果这两个写在不同的 framework 里,Xcode 不会提示。在 8 的时候,这个 size 的调用最后会走到 OC 的方法,但是在 9 的时候,在 Swift 代码里引入这个 OC framework,代码就直接崩溃了,会不知道应该调用那个库的 size。这显然是编译器的一个 bug,但这也侧面反映了,OC 和 Swift 混编带来的问题越来越多,两个体系的区别会越来越大。

总结

迁移到 4.0 的代价比之前要小的多, ABI 稳定很大可能在 5.0 到来。对于观望 Swift 是否稳定的开发者而言是个好消息,相信 Swift 的接受程度会更高。Swift 一年一个版本的升级和 OC 的分野会越来越大,给混编带来了很多的不确定性,对于混编的项目有能力的还是把一些代码迁移到 Swift。

对于 Xcode 我有一个经验再次和大家分享一下:Xcode 有两个版本,一个不稳定的版本和一个更不稳定的版本。

Swift 4迁移总结:喜忧参半,新的起点的更多相关文章

  1. 猿题库从 Objective-C 到 Swift 的迁移

    猿题库从 Objective-C 到 Swift 的迁移 引言 相信没有人会怀疑,Swift 是 iOS 开发未来的主流语言,但是由于 Swift 语言的不断变化以及庞大的迁移成本,真正把项目迁移到 ...

  2. 辞 = or != 一个新的起点!!!

    辞职!他离开了公司工作三年以上.怀旧也许是一个暗示.伍德还可能有丝毫的遗憾! 简而言之.其结果是坚决离开.在一个.NET程序员的身份进入公司,但仅做了一个月.NET,而仍保持,台,框架,自己的语言!就 ...

  3. Swift 3.1 的一些新特性

    Swift 3.1 的一些新特性   推荐序 本文来自泊学的投稿,介绍了 Swift 3.1 的新特性,感谢泊学授权发表.以下为文章正文. 正文 Apple 终于发布了Xcode 8.3以及Swift ...

  4. Swift 3到5.1新特性整理

    本文转载自:https://hicc.me/whats-new-in-swift-3-to-5-1/,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有. Hipo 2.0 重写从 Swif ...

  5. iOS8.3发布了Swift 1.2带来哪些新变化

    苹果前几日在面向开发者推送iOS 8.3 Beta的同时,还发布了版本号为6D520o的Xcode 6.3 Beta,其中便包含了iOS 8.3 Beta和OS X v10.10 SDK,并进一步提升 ...

  6. Swift 3 迁移工作总结

    写在前面 Swift 3.0 正式版发布了差不多快一个月了,断断续续的把手上和 Swift 相关的迁移到了Swift 3.0.所以写点小总结. 背景 代码量(4万行) 首先,我是今年年初才开始入手 S ...

  7. Swift 2.0 到底「新」在哪?

    [编者按]2015年6月,一年一度的苹果 WWDC 大会如期而至,在大会上苹果发布了 Swift 2.0,引入了很多新的特性,以帮助开发者更快.更简单地构建应用.本篇文章作者是 Maxime defa ...

  8. Swift 3必看:新的访问控制fileprivate和open

    在swift 3中新增加了两中访问控制权限 fileprivate和 open.下面将对这两种新增访问控制做详细介绍. fileprivate 在原有的swift中的 private其实并不是真正的私 ...

  9. 从以前的项目格式迁移到 VS2017 新项目格式

    以前的项目格式使用的是 csproj 的格式,但是 .net core 支持使用 project.json 格式的项目文件,后来还是决定不使用这个格式. VS2017 的项目格式更好读.更简单而且减少 ...

随机推荐

  1. mybatis DATE_FORMAT 格式化时间输出

    参考:http://www.cnblogs.com/yangy608/p/3950095.html 一.在oracle中,当想把字符串为‘2011-09-20 08:30:45’的格式转化为日期格式, ...

  2. QMessageBox的用法

    QMessageBox的用法   先来看一下最熟悉的QMessageBox::information.我们在以前的代码中这样使用过:   QMessageBox::information(NULL,  ...

  3. kruskal证明

    Kruskal算法证明   易证,对于一个无向加权连通图,总是存在一棵或以上的有限课生成树,而这些生成树中肯定存在至少一棵最小生成树.下面证明Kruskal算法构造的生成树是这些最小生成树中的一棵. ...

  4. MIT-6.824 Raft协议

    摘要 raft是一种比paxos容易理解的一致性算法,实现起来比paxos简单许多.本文前部分描述算法的细节,后部分尝试探讨下该算法的原理. 算法描述 raft算法之所以简单的原因之一是它将问题分解成 ...

  5. Windows10下 tensorflow-gpu 配置

    引言 越来越多的的人入坑机器学习,深度学习,tensorflow 作为目前十分流行又强大的一个框架,自然会有越来越多的新人(我也刚入门)准备使用,一般装的都是 CPU 版的 tensorflow,然而 ...

  6. Playmaker全面实践教程之playMaker编辑器

    Playmaker全面实践教程之playMaker编辑器 playMaker编辑器 playMaker编辑器是制作状态机的主要视图,如图1-23所示.只有熟悉此视图,读者才能更加快捷的使用Playma ...

  7. BZOJ.3510.首都(LCT 启发式合并 树的重心)

    题目链接 BZOJ 洛谷 详见这. 求所有点到某个点距离和最短,即求树的重心.考虑如何动态维护. 两棵子树合并后的重心一定在两棵树的重心之间那条链上,所以在合并的时候用启发式合并,每合并一个点检查sz ...

  8. [模板][P3796]AC自动机(加强版)

    Description: 输出有哪些模式串在文本串中出现次数最多,这个次数是多少 Hint: 多组数据,$ len_{文本串}<=10^6,\sum len_{模式串} <= 70*150 ...

  9. j2me必备之网络开发数据处理

    第9章 无线网络开发MIDP提供了一组通用的网络开发接口,用来针对不同的无线网络应用可以采取不同的开发接口.基于CLDC的网络支持是由统一网络连接框架(Generic Connection Frame ...

  10. E: Unable to locate package openjdk-8-jdk 及java version 切换

    在unbuntu14.04系统上安装 Open JDK 8 时遇到了如下问题: $ -jdk Reading package lists... Done Building dependency tre ...