[编程开发] 都说swift取代oc,为何五年了依然是oc为主?

[复制链接]
我有点懒 发表于 2023-10-4 18:05:34|来自:北京 | 显示全部楼层 |阅读模式
swift5之后的abi稳定是否会改善这一局面?flutter和rn会进一步挤压原生开发市场吗?
全部回复5 显示全部楼层
boat 发表于 2023-10-4 18:06:09|来自:北京 | 显示全部楼层
说个情况,以我个人周围的圈子为例:
高德老东家,目前主要OC,已在接入Swift。
微博同学,也主要OC,新业务可OC可Swift。
京东同事,主要是OC,目前在组件化,新的业务用Swift。
其他去了小公司的同事,目前两年基本也都使用Swift。
我2013年开始使用OC,在老东家(高德)用了好几年。出来后到新公司,除了刚开始接手的老项目OC与Swift混编,新项目一律Swift。目前使用Swift三年多。说句心里话,习惯Swift了,就不太想继续用OC。一是语法简洁,代码量会少很多,二是面向协议的思维方式和可玩性高。
总结:截止目前,你能看出,老项目由于历史原因主要OC,但在往Swift路上走。新项目主流的还是Swift。
lxi4509 发表于 2023-10-4 18:06:22|来自:北京 | 显示全部楼层
Swift 在 WWDC14 正式发布到 2019,经过 5 年的不断迭代,这其中经历了标准库变动,语法的增减。
首先使用 Swift 作为开发语言的开发者们都苦不堪言,戏称《Swift 从入门到重学》,几乎每一年 Swift 都会迎来比较大的改动,甚至 API 都发生了变化。
WWDC 19 苹果发布了 Swift 5.0,苹果终于宣布 Swift 的 ABI 稳定。这标志着 Swift 这门语言已经趋于稳定,在 2019 至 2020 的迭代中,Swift 5.2 也做到了模块稳定,之前的大修大改已经不会再出现了。


有意思的是,在 WWDC16 中有一页 PPT 写下了 Goals for Swift 3:
Develop an open community
Portability to new platforms
Get the fundamentals right
Optimize for awesomenss
如今已经 2020 年,再回头看这些目标,Swift 5.3 几乎完全实现了。Swift 可谓一直不忘初心,朝着认为正确的方向不断的努力。苹果推出 Swift 就是为了摆脱 OC 的束缚,让它能更好的践行现代的编程理论,所以才会诞生出 SwiftUI,才会有 Combine、map/filter/reduce 等这些库和 API。
这次我们想针对WWDC 2020上 Swift 的最新信息,来聊聊它的未来趋势和机会。
本篇回答内容来自阿里巴巴淘系技术部无线开发工程师 星志。
——————————————————————————————————————
语法的不断成熟


每年 WWDC 比较期待的一个点就是看看 Swift 又加了一些什么新奇爽快的语法。我先列举一下 Swift 5.3 新增的语法:

  • [SE-0249] KeyPath as Function
  • [SE-0279] Multiple trailing closure
  • [SE-0281] Type-based program entry point (@main)
  • [SE-0266] Synthesized comparable conformation for enum types
  • [SE-0269] Increased availability of implicit self in closure
  • [SE-0276] Multi-pattern catch clauses
  • [SE-0280] Enum cases as protocol witnesses
  • [SE-0267] Where clauses on contextually generic declarations
  • [SE-0270] Collection operations on noncontiguous elements
  • [SE-0264] Standard library preview package
  • [SE-0253] Callable values of user-defined nominal types
  • [SE-0263] String initializer with access to uninitialized storage

上面列举的 12 个语法改动,有兴趣的同学可以到 swift-evolution 去查看详细的内容。其中比较有意思的几个改动就是 [SE-279],[SE-281]和[SE-0269],我们来细细评味一下。

Design for SwiftUI

[SE-279] Multiple trailing closure 多重尾闭包这个新特性算是一个非常大的改动。这个特性的出现影响了 Swift 非常重要的地方,API 设计。先来几个官方的例子:
// 1. Single closure argument -> trailing closure
UIView.animate(withDuration: 0.3) {
  self.view.alpha = 0
}
// 2. With trailing closure
UIView.animate(withDuration: 0.3, animations: {
  self.view.alpha = 0
}) { _ in
  self.view.removeFromSuperview()
}
// 3. Multiple closure arguments -> no trailing closure
UIView.animate(withDuration: 0.3, animations: {
  self.view.alpha = 0
}, completion: { _ in
  self.view.removeFromSuperview()
})
// 4. Multiple trailing closure arguments
UIView.animate(withDuration: 0.3) {
  self.view.alpha = 0
} completion: { _ in
  self.view.removeFromSuperview()
}上面的代码中 2 的情况是经常出现的,尾闭包的含义就不够明确,以前最佳的方式应该为 3,但是两个闭包被套在一个小括号里,使得括号多重嵌套,可读性下降。为了解决这个问题,苹果使用了第 4 中方法--多重尾闭包。可以从代码看出可读性得到了很大的提升。
这一看似优雅的设计其实引入了很多语言的复杂度,有了这个特性你甚至可以写出类似下面的代码,看上去就像是创造了一个 if-else 语句,但其实它是一个函数。
func when<T>(
  _ condition: @autoclosure () -> Bool,
  then: () -> T,
  `else`: () -> T
) -> T {
  condition() ? then() : `else`()
}

// using syntax
when(2 < 3) {
  print("then")
} else: {
  print("else")
}

// equivalent to:
when(2 < 3, then: { print("then") }, else: { print("else") })这就对 SDK 的开发者提出了更高的要求,需要小心的使用这个特性来设计 API,防止这个特性被滥用导致代码的可读性下降,甚至造成歧义。苹果在 WWDC20 中也强调了这一点。
还有两个特性其实很简单,[SE-0281] 是 @main 来标记程序入口,[SE-0269] 是让开发者在特定的情况下不需要再写多余的 self.。
苹果推出了这几个语言特性,就是为了让战略性的项目 SwiftUI 的 API 更加简洁明了。可以看下面的例子:
@main // <- @main
struct MyApp: App {
    var body: Scene {
        WindowGroup {
            Text("Hello World!")
        }
    }
}
//------
Gauge(value: acidity, in: 3...10) {
    Image(systemName: "drop.fill")
} currentValueLabel: { // <- multiple trailing closure
    Text("\(acidity, specifier: "%.1f")")
} minimumValueLabel: {
    Text("3")
} maximumValueLabel: {
    Text("10")
}
//------
struct ContentView : View {
    var landmark: Landmark
    var body: some View {
        Button(action: {
            landmark // <- no self.
        }) {
            Text("Button")
        }
    }
}苹果也不是第一次为了 SwiftUI 改 Swift 的语法,[SE-0255] Implicit returns from single-expression functions 就是为了让 SwiftUI 的 body 不用写 return,强化 DSL 风格。
苹果为了 SwiftUI,推出了 functionBuilder 来实现 DSL 形式的代码;为了 SwiftUI,推出了许多让它更漂亮的语法特性;为了 SwiftUI,不惜为语言引入更多的复杂度。

下限低,上限高


Swift 的最初的设计方向就导致了它是一门下限很低上限很高,入门容易精通难,使用容易设计难的语言。它一系列的语法糖和语法设计,包括类型推断系统,都是让它成为十分亲民的语言,而它的一系列语法特性,让它在设计 API、SDK实现的时候其复杂程度也不亚于其他语言。

Swift is a general-purpose, multi-paradigm, compiled programming language developed by Apple Inc. for iOS, iPadOS, macOS, watchOS, tvOS, and Linux.
---- Wikipedia

维基百科的后半部分可能有些局限了,但是前半部分说明了它是一门多编程范式的语言,Swift 可以支持 面向对象编程(OOP),面向协议编程(OPP),声明式编程(DP),函数式编程(FP),泛型编程(GP)。
Objective-C 已经发展了这么多年,如此成熟,为什么现在苹果要开始抛开它?Objective-C 本来就是生于一个面向对象编程范式起飞的一年,与 C++ 一样为了拓展 C 命令式编程范式而诞生的语言。当时 C 语言虽然也可以实现 OOP,但是语法设计成为了限制。在当代计算机编程语言研究演进下,出现了很多编程范式的新理论,如函数式编程,元编程等等,同样 OC 可以通过它的方式来实现,但是语言的冗杂和 OOP 的设计已经不能更好的表达这些概念,就犹如纯 C 来表达OOP 一样。
苹果推出 Swift 就是为了摆脱 OC 的束缚,让它能更好的践行现代的编程理论,所以才会诞生出 SwiftUI,才会有 Combine、map/filter/reduce 等这些库和 API。类型推断和元编程的理论也让 Swift 在保留强类型的环境下还能保持如此简洁优雅,可读性强的代码。而这些是 OC 无法做到的。尝试使用 OC 对这些现代概念做表达的 SDK 都会显得十分冗杂。
现在 Swift 语法已经不会再大变,有如此现代、安全、稳定、富有想象力的语言,有什么理由不真香呢?

土壤已经肥沃

我们先通过下面的脑图感受一下 Swift 更迭到 5.3 已经取得的成就。



现在 Swift 生态环境已经自成一派,有一套完整的工具链保证开发,有更独立的标准库让它可以自由迁移,包管理让丰富了它的 SDK,同时还具有 Native 语言的各种优势。在这么多年的发展中,它的能力已经触及到了 AI、Server、Mobile Device、FaaS,强大的标准库让它甚至可以当脚本语言使用。
Swift 如今已经不再孤立无援,开源让 Swift 变得生机勃勃,合理优雅的设计和开放的态度让全球的开发者们都在不断的完善它。
在 Swift 的大生态中,包管理工具是最值得一说的。一门语言它的能力,取决于它是否有强有力的 SDK,还有就是获取他们的途径。基础的 Swift 的能力都由工具链和标准库提供,而强有力的 SDK 最好的方式就是通过包管理工具快速获取。Swift Package Manager 就是 Swift 的军械库。

Swift Package Manager

看一下 Swift Package Manager(SPM) 的发展历程,SPM 从 Swift 3.0 时就发布,当时只支持 Git 远端仓库,支持支源码发布。WWDC 19,Xcode 引入了一个新的架构 XCFramework,一个旨在能打包多个平台 framework 的文件结构。WWDC20 SPM 宣布正式支持发布二进制 framework。
WWDC20 SPM 走出的这一步标志着功能的完善。为什么这么说,因为在 iOS 届,解决了 Xcode 无包管理工具难题,让众多优秀的开源库能被快速获取的包管理工具 -- Cocoapods。在 SPM 出现之前,Cocoapods 的功能已经非常完善,打败了当时另外的一款包管理工具 Carthage。
Cocoapods 作为基于 Xcode 开发的第三方包管理工具,通过修改 Xcode 的工程信息来实现处理各个包的依赖问题。它支持依赖的二进制分发、源代码分发,基于 framework 良好的资源管理。现在许多公司的大型 App 也是用 Cocoapods 做模块化组件分离,通过二进制依赖的方式来提高打包速度。
然而比较可惜的是它工作流是脱离 Xcode 的,Podfile 更新等操作都是在工程之外。语言使用的是 Ruby,虽然使用了一些操作使 Podfile 变成了 DSL,但是对于开发者而言是有一定门槛的,特别是需要编辑发布 SDK 所使用的 podspec 时,对照文档,无代码提示的编写让写正确配置文件都成了难事。Cocoapods 还不得不设计出 podspec lint 来帮组开发者确认这个事情。
对于 Swift PM 这个亲儿子而言,就不存在这个问题,SPM 已经深入的集成到了 Xcode 中,所有的操作都可以利用 Xcode 完成。在编写 Swift Package 时,Xcode 现在已经具备将 Package.swift 作为工程项目打开,并且现在工程模板中已经包含了 Swift Package。强大的 Xcode 自动补全让编写 Package.swift 不再是一件难事。如果脱离 Xcode,利用 swift-lsp 结合现在热门的文本编辑器,如 VSCode 等都可以实现相应的功能。SPM 现在已经是独立于 Xcode 的存在,可以为 Swift 提供强有力的支持。
SPM 在功能层面已经不逊于 Cocoapods,在 WWDC20 时,SPM 已经支持以二进制库形式分发 Package,SPM 也可以管理包中的资源和本地化,基本的能力已经与 Cocoapods 差异不大,然而最关键的是,SPM 是纯 Swift ,开源,还有苹果官方支持的包管理工具。

新瓶酿酒酒更香


国外的不少 APP 已经迁移到了 Swift;三方开源库如 AFNetworking 已经用 Swift 重写为 Alamofire,Lottie 已经完全被 Swift 重写替代。苹果也推出了许多 Swift Only 的库。苹果也在利用 Swift 为 UIKit,GCD 等基础库不断提供更具有表现力的 API。
Uber 完成了迁移,收获了 Swift 极强的稳定性。Alamofire,SnapKit 用  Swift 重写,获得了更加具有表现力的 API,开发者更容易接受且喜爱。 Reactive 系列的编程风格在 Swift 上大放异彩。

机会与展望

现在 Swift 发展了这么多年,遍地开花,Objective-C 已经有在逐渐被废弃的趋势。现在很有可能都很难招到认真学习过 OC 的应届生了。
Swift 在集团内部的发展,还有很多的工作要做,这其中充满了挑战。我们也在积极探索 Swift 在手淘的落地,取得了 Swift 5.1 能模块在手淘中正确运行起来的阶段性成就。但是比较遗憾的是还有很多模块是无法让 Swift 正确跑起来的,以现在的工具链来说甚至源码依赖调试都无法做到。
但是这都是暂时的,现在时机已经成熟,Swift的语言特性,SPM,工具链,标准库都已经足够强大。未来,我们会尽快大力升级 Swift 的基建。让 Swift 的花在集团内开起。先定个小目标,希望 Swift 能成为集团 iOS 客户端开发的首选语言。

参考


  • SwiftUI 背后那些事儿
  • WWDC20 What's new in Swift
  • WWDC19 What's new in Swift
  • WWDC18 What's new in Swift
  • WWDC17 What's new in Swift
  • WWDC16 What's new in Swift
  • WWDC20 Swift packages: Resources and localization
  • WWDC20 What's new in SwiftUI
  • Swift 5 时代的机遇与挑战到底在哪里?
  • Swift Evolution

————————————————————————————————————

本账号主体为阿里巴巴淘系技术,淘系技术部隶属于阿里巴巴新零售技术事业群,旗下包含淘宝技术、天猫技术、农村淘宝技术、闲鱼、躺平等团队和业务,是一支是具有商业和技术双重基因的螺旋体。
入驻知乎,将会给大家带来超多干货分享,立体化输出我们对于技术和商业的思考与见解。
详情介绍可以看这里 阿里巴巴淘系技术介绍
欢迎收藏点赞关注我们!共同进步~ :)
shk8716 发表于 2023-10-4 18:06:37|来自:北京 | 显示全部楼层
1. OC语言本身并不存在什么硬伤
2. 存量太大,迁移成本高且收益不明显
说无脑切swift的绝壁没见过大工程。OC毕竟那么多年了,尤其国内大公司都追逐超级App的梦,端上代码量都大的一批,没几百个组件上百万行代码哪好意思说自己是超级App。
你跟你老板说我花半年的时间全部把OC迁移到swift,你告诉老板说以后开发效率会提高,但是你搞完了觉得自己牛逼了,跳槽走了,留下一堆一堆的bug,老板黑人问号.jpg
3. 之前ABI不稳定,对于二进制化是个深坑
懂的人自然懂,都是泪。不过好在ABI已经稳定了。
4. 最重要的是:人的因素
放到最后是因为这条会得罪人。从去年开始转到基础组,不少都是横向推动的需求,讲真,不是所有人都把写好代码作为一种追求,大概率人家只是混口饭吃。连清个warning都会有人说,“我这是配合你工作!”
我¥@*%#!!!!
据我观察,iOS程序员都不怎么爱折腾,所以你看iOS开发一直处于不温不火,不是说没得折腾,而是愿意折腾的人很少,所以整个生态趋于稳定。iOS这边的框架都是很多年前就有得了,对比前端基本每两三年就换个底儿掉,可窥一二。是真的iOS框架成熟??
一个方案可不可行在iOS这边都是明确的,不像Android总有各种猥琐的办法,毕竟源码摆在那了。苹果也一直想让开发越简单越好,小而美的app是苹果最喜欢的,苹果对大工程支持的像shi一样就能看得出来。这个就给整个环境定了一个基调,别乱搞事情。(反例就参考热修)
当然还会有有个别老古董会告诉你swift这不好那不好,当然了,人家会拿出一万个理由来告诉你不要用swift,就像当年他们不让用ARC一样,这种人呀,我只能说,您都中年了,小心着点吧。
强推swift的是年轻,疯狂拒绝的是古董。个人觉得,最好的办法就是提供一个swift的可用环境,然后新的组件看看向swift过渡,急不得,也别抗拒。
不过最后得补一句,对于高阶程序员来说,语言真的不叫事。能很好的解决问题才是关键,语言只是一个工具。

我都写半年Ruby了我说啥了(滑稽脸)。
defiler 发表于 2023-10-4 18:06:52|来自:北京 | 显示全部楼层

  • 先说现状
国外的 Swift 普及率比国内高。
现在国内公司开全新项目,Swift 已经占压倒性优势了。
很多以前是 OC 的项目也转向 OC/Swift 混编了。
但是也有对包大小非常敏感的项目,还是纯 OC 开发。不少公司刚刚摆脱 MRC 不久,业务压力大,历史包袱重,没有时间推进新技术。

2020.06.28 更新---
淘宝、携程已经开始做 Swift 支持。按照国内一窝蜂的风格,今年估计各大厂都会陆续支持,毕竟都是 KPI。
2020.06.28 更新结束---
2. 对比一下 OC 和 Swift
总的来说,Swift 相对于 OC 来说,是进步的。Swift 有很多好的语言特性,能做更好的抽象。
说 Swift 线上崩溃 线下 Delay 的不怎么会写代码吧?强类型能帮你纠正很多低级错误。Swift 不乱用不熟悉的特性,写起来除了把 []换成.毫无区别,再不济所有声明都加上 @objc ,这够狠了吧,要是还能出问题也称不上合格的开发者了。
关于 OC 的黑魔法,能玩的也就是 runtime 了, Method/Class Swizzling, AOP,转发等等。Swift 确实没有这么灵活,但是说实话大型项目,category 都不敢乱写,就别说这些花活了,你写的黑魔法不知道会影响到谁。要是你的骚操作给别人带来了 bug,不得被人花式骂死?
我就遇到过两次,一次是别人 hook 了 UI 组件的方法,我们这边展示异常,百思不得其解,后来一条一条看调用栈才有了点眉目揪出了问题。
第二次差不多,别人 hook 了 UIAnimation 的方法,但是没考虑周全,导致了崩溃,也是得看调用栈。
Swift 也有很多灵活的东西可以玩啊,比如方法=闭包,比 OC 那个灵活多了,@selector() 真的很不好用。
还有就是要吐槽 OC 没有包名,有的时候真的欲哭无泪,无穷无尽的问题。
Xcode 对 Swift 的支持特别不好,代码提示动不动就没了,打开混编项目不用打字,放在那风扇就狂转,续航从 10 小时降到 2 小时。还有最搞笑的,如果声明一个数组,不显式的指定类型,那就等着哭吧,编译器会一个一个元素的去推断类型,最后得出数组的范型。我试过声明一个40个元素的数组,然后这个文件编译了20分钟。还好这个 bug 现在修掉了。
3. 对比一下 Swift 和 Kotlin
使用下来感觉 Swift 不如 Kotlin。Swift 的 API 不如 Kotlin,比如在可选型解包的的时候,要繁琐的多。Kotlin 和 Java 能无缝对接,但是 Swift 和 OC 是两门语言,混编的时候比较痛苦,主要是需要不断的考虑,我用的特性 OC 支持不支持,这个类要不要暴露给 OC 使用,现在用了高级特性,万一将来 OC 要调用要怎么兼容,很头痛。
4. Swift ABI 变动
还拿 ABI 说事的也好多年没写代码了吧?Swift 3 4 5 ABI 变动很小,迁移成本不高。另外 Xcode 会支持当前最新版本以及上一个版本的 Swift,比如现在最新的是 4.0,那 3.0 的代码也可以编译。
5. 关于 RN 和 Flutter
RN 有点凉的趋势,最近苹果的审核收紧了,RN 有可能被当作热更新导致 APP 审核被拒了。
Flutter 大家还都是玩票,而且应用下来看崩溃率有点太高了。
另外就是 Dart 。。。。一切皆 widget 听起来很美好,但是写起来缩进看的快吐了。
yang1030 发表于 2023-10-4 18:07:21|来自:北京 | 显示全部楼层
今年ABI稳定了应该就会开始大面积使用了
Swift刚出来那几年升级一个版本就要重新适配,早期版本语法都不太稳定
现在基本上已经固定了,增加的语法糖都比较少了,增加的更多都是新特性这样
这次随着iOS13发布,ABI稳定之后,iOS包可以不用带8MB的库了
虽然在AOP和Runtime方面比起OC的各种黑科技还有些不足,但已经不是会干扰常规项目开发的程度了
强烈建议各位在iOS13和新的Swift版本发布之后切换

快速回帖

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则