Swift 4迁移总结:喜忧参半,新的起点
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迁移总结:喜忧参半,新的起点的更多相关文章
- 猿题库从 Objective-C 到 Swift 的迁移
猿题库从 Objective-C 到 Swift 的迁移 引言 相信没有人会怀疑,Swift 是 iOS 开发未来的主流语言,但是由于 Swift 语言的不断变化以及庞大的迁移成本,真正把项目迁移到 ...
- 辞 = or != 一个新的起点!!!
辞职!他离开了公司工作三年以上.怀旧也许是一个暗示.伍德还可能有丝毫的遗憾! 简而言之.其结果是坚决离开.在一个.NET程序员的身份进入公司,但仅做了一个月.NET,而仍保持,台,框架,自己的语言!就 ...
- Swift 3.1 的一些新特性
Swift 3.1 的一些新特性 推荐序 本文来自泊学的投稿,介绍了 Swift 3.1 的新特性,感谢泊学授权发表.以下为文章正文. 正文 Apple 终于发布了Xcode 8.3以及Swift ...
- Swift 3到5.1新特性整理
本文转载自:https://hicc.me/whats-new-in-swift-3-to-5-1/,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有. Hipo 2.0 重写从 Swif ...
- iOS8.3发布了Swift 1.2带来哪些新变化
苹果前几日在面向开发者推送iOS 8.3 Beta的同时,还发布了版本号为6D520o的Xcode 6.3 Beta,其中便包含了iOS 8.3 Beta和OS X v10.10 SDK,并进一步提升 ...
- Swift 3 迁移工作总结
写在前面 Swift 3.0 正式版发布了差不多快一个月了,断断续续的把手上和 Swift 相关的迁移到了Swift 3.0.所以写点小总结. 背景 代码量(4万行) 首先,我是今年年初才开始入手 S ...
- Swift 2.0 到底「新」在哪?
[编者按]2015年6月,一年一度的苹果 WWDC 大会如期而至,在大会上苹果发布了 Swift 2.0,引入了很多新的特性,以帮助开发者更快.更简单地构建应用.本篇文章作者是 Maxime defa ...
- Swift 3必看:新的访问控制fileprivate和open
在swift 3中新增加了两中访问控制权限 fileprivate和 open.下面将对这两种新增访问控制做详细介绍. fileprivate 在原有的swift中的 private其实并不是真正的私 ...
- 从以前的项目格式迁移到 VS2017 新项目格式
以前的项目格式使用的是 csproj 的格式,但是 .net core 支持使用 project.json 格式的项目文件,后来还是决定不使用这个格式. VS2017 的项目格式更好读.更简单而且减少 ...
随机推荐
- input禁止输入空格
<input name="" onkeyup="this.value=this.value.replace(/^\s+|\s+$/g,'')" value ...
- spring 注解与配置文件启动配置使用原理
遇到个问题注解配置文件调用配置文件JSF服务,worker起不来. 待续...
- hihoCoder.1509.异或排序(位运算 思路)
题目链接 \(Description\) 给定长为\(n\)的序列\(A\).求有多少\(S\),满足\(0\leq S<2^{60}\),且对于所有\(i\in[1,n-1]\),\(a[i] ...
- 最全的JS判断是否为中文的方法
第一种代码:EXFCODE:1 function isChinese(temp)2 {3 var re=/[^/u4e00-/u9fa5]/;4 if (re. ...
- Android的onLayout、layout方法讲解
onLayout方法是ViewGroup中子View的布局方法,用于放置子View的位置.放置子View很简单,只需在重写onLayout方法,然后获取子View的实例,调用子View的layout方 ...
- java的关键字与保留字
1,Java 关键字列表 (依字母排序 共50组): abstract, assert, boolean, break, byte, case, catch, char, class, const(保 ...
- 网络编程(1)—TCP
java.net 包中提供了两种常见的网络协议的支持: TCP:TCP 是传输控制协议的缩写,它保障了两个应用程序之间的可靠通信.通常用于互联网协议,被称 TCP / IP. TCP协议: 使用TCP ...
- AngularJS中有关Directive的汇总
本篇通过几个例子对AngularJS中的Directive进行汇总. 例子1,单向绑定和双向绑定 <html ng-app="myApp"> <head> ...
- uboot的常用命令及用法
转自:https://blog.csdn.net/jklinux/article/details/72638830 https://blog.csdn.net/dagefeijiqumeiguo/ar ...
- Go语言之高级篇beego框架之模型(Models)
一.模型(Models) 1.beego-orm的相关特性 支持 Go 的所有类型存储 -轻松上手,采用简单的 CRUD 风格 -自动 Join 关联表 跨数据库兼容查询 允许直接使用 SQL 查询/ ...