Swift vs. Objective-C:未来看好Swift的十个理由

yge3 9年前

英文原文:Swift vs. Objective-C: 10 reasons the future favors Swift 

是时候使用易入手又全面的 Swif 语言为 iOS 和 mac OS X 做应用开发了。 

虽然编程语言不会那么容易消逝,但坚持衰落范例的开发小组正在这么做。如果你正为移动设备开发应用程序,并且你还没有研究 Swift,那么注意:当 Swift 涉及到 Mac、iPhone、ipad、Apple Watch 和未来设备的应用开发时,它不仅会排挤掉 Objective-C,而且还会取代在 Apple 平台中做嵌入式开发的C语言。 

由于几个关键特性,在未来几年,Swift 有很大潜力成为创造身临其境的、响应迅速的、面向用户的应用程序的实际编程语言。 

苹果公司似乎在 Swift 上还有更大的目标。它的编译器性能和开发语言都被优化了,苹果公司在 Swift 的文档中暗示 Swift 被设计成小能(显示)“hello,world”,大能(完成)整个操作系统。苹果公司还没把这门语言的目标说全,Xcode6,Playgrounds 和 Swift 的推出就一起揭露苹果的意图:更简单的应用开发,更易用的开发工具链。 

这是从现在起使用 Swift 工作,并走在比赛前列的 10 个原因。 

1. Swift 容易阅读 

如你所能预计到的一门基于 C 构建的语言,Objective-C 身上所有的毒疣子都有。为了将关键词和类型同C的类型作区分,Objective-C 使用@符号引入了新的关键词。因为 Swift 不是基于C构建的,它同意了所有的关键词,并将 Objective-C 类型和对象相关的关键词前面大量的@符号移除了. 

Swift 丢弃了遗留下来的约定。因而你不再需要行尾的分号,以及 if/else 语句中围绕条件表达式的括弧。另外一个大变化就是方法的调用不再互相嵌套成中括号的深坑 -- 再见吧,[[[ ]]]。Swift 中的方法和函数的调用使用行业内标准的在一对括弧内使用逗号分隔的参数列表。这样做的结果就是一种带有简化了句法和语法的更加干净有表现力的语言。 

除了其它当代流行的编程语言之外,Swift 更像是自然的英语了。这种可读性是的其很容易能被其它来自 JavaScript,Java,Python,C#,以及 C++ 的开发者纳入到他们的工具链之中 -- 一点也不像 Objective-C 这只笨笨的黄小鸭。 

2. Swift 更易于维护 

历史遗留问题会让 Objective-C 越来越倒退 -- C 没有演进的话,这个语言也就跟着无法进行演进。C 需要程序员维护两套代码文件,以优化构建的时间以及创建可执行 app 的效率, 这种需要延续到了 Objective-C 上。 

Swift 丢掉了对着俩文件的要求。Swift1.2 中 Xcode 和 LLVM 编译器可以自动计算出以来并执行增量构建。如此,将内容清单 (头文件) 同内容主体(实现文件)相分离。Swift 将 Objective-C 头文件(.h) 和实现文件 (.m) 合并成了一个代码文件 (.swift)。 

Objective-C 的两份文件系统存在强加给程序员的额外工作 -- 而这些工作会让程序员难免分心而不能顾全大局. 在 Objective-C 中你不得不手动去同步文件之间的方法名称和注释, 有时候要寄希望于一个约定好的标准,不过除非团队的规矩和代码审查制度到位,否则这是不会为你提供什么保障的。 

Xcode 和 LLVM 编译器可以在幕后做一些工作来减轻程序员的工作负担. 使用 Swift, 程序员可以少做些费脑力的记忆性工作,从而能在创建 app 逻辑的工作上面赢得更多的时间. Swift 为我们程序员裁掉了那些样板式的工作,同时对代码、注释以及所要支持的特性的质量都有所提升。 

3. Swift 更加安全 

Objective-C 有意思的一个方面是指针 -- 特别是 nil (null) 指针 -- 它们被处理的方式. 在 Objective 中-C, 如果你调用方法的是一个值为 nil (未初始化)的指针变量,什么事情都会不发生. 表达式或者一行操作变成了一项空操作(no-operation (no-op)), 而这就使得其看起来会有不会奔溃的好处, 但其实它已经变成了一个巨大的 bug 来源. no-op 会导致不可预测的行为, 这是程序员在尝试找出并修复某种随机的奔溃,或者要停止反常的行为时所要面对的敌人。 

在 Swift 代码中的可选类型使得一个 nil 可选值的可能性变得非常的明确, 这意味它能在你写下一段糟糕的代码时会生成一个编译器错误. 这就建立了一种短程反馈的循环,可以让程序员带着目标去写代码. 问题在代码被写就时就可以被修复, 这大大节省了你要在修复有关来自 Objective-C 指针逻辑的 bug 时需要耗费的时间和金钱。 

在 Objective-C 的传统中, 如果某个值返回自一个方法, (使用注释以及方法的命名约定来)说明指针变量被返回的行为是程序员的责任.在 Swift 中, 可选类型和值类型使得方法定义中值是否存在,或者其有可能是可选的(即值可能存在也可能为 nil),这些问题都是很明确清楚的。 

为了提供对行为的预测,Swift 会在 nil 可选值被使用时触发一次运行时崩溃。 崩溃提供的就是一种一致的行为,它能减轻修复 bug 过程的压力,因为它会直白地强制让程序员修复好这个问题. Swift 运行时崩溃的时候会停在 nil 可选值被使用到的那行代码处。这就意味着 bug 能更早的被修复,并能在 Swift 代码中被完全的规避掉。 

4. Swift 的内存管理是统一化的 

Swift 以一种 Objective-C 从未有过的方式进行了统一。对自动引用计数 (ARC) 的支持是在整个过程化的和面向对象的代码路径上完成的。在。Objective-C。中, ARC 在 Cocoa API 和面向对象代码中获得支持;然而它并不支持过程式的 C 语言代码和像 Core Graphics 这样的 API。这意味着在使用 Core Graphics API 以及其它 iOS 上的底层 API 时,内存管控的处理都是程序员的责任。程序员在 Objective-C 上会遇到的大量内存溢出问题在 Swift 上是不可能的。 

程序员不应该为他或她创建的数字对象去考虑内存的问题。因为 ARC 在编译时就处理了所有的内存管理事务, 内存管理所有消耗的脑力现在可以被用来专注于核心的应用逻辑以及新的功能特性。因为 Swift 中的 ARC 在过程式的和面向对象的代码中都能起作用,它也就不再需要程序员进行心理上的上下文切换了, 即使是他们在编写要触及底层 API 的代码时也不需要 -- 这在目前版本的 Objective-C 中就是一个实实在在的问题。 

自动和高性能的内存管理是一个已经被解决的问题,而苹果公司已经证明了这个问题的解决可以提高生产力. 另外一个副作用就是 Objective-C 和 Swift 不会像 Java,Go 或者 C# 那样遇到垃圾收集器针对没有被使用的内存运行清理作业的情况. 这对于那些将会被用于相应图形和用户输入的编程语言而言就是一个非常重要的要素, 特别是在诸如 iPhone、Apple Watch 以及 iPad 这样的(如果响应滞后就会让用户感知上以为应用是坏的)触摸屏设备上。 

5. Swift 代码更少 

Swift 减少了重复性语句和字符串操作所需要的代码量。在 Objective-C 中, 使用文本字符串将两块信息组合起来的操作非常繁琐。Swift 采用当代编程语言的特性,比如使用“+”操作符将两个字符串加到一起,这在 Objective-C 中是没有。像这样支持对字符和字串的组合对于任何要在屏幕上向用户展示文本的编程语言的基础设施。 

Swift 中的类型系统减少了代码语句的复杂性--作为编译器可以理解的类型。比如,Objective-C 要求程序员记住特殊字符标记(%s,%d,%@)并且提供了一个用逗号分隔的变量来代替每个标记。Swift 支持字符串插入,这就消除了需要记住的标记和允许程序员直接插入变量到面向用户的字符串中,比如标签或者按钮的标题。这类推理系统和字符串插入减少错误来 源在 Objective-C 中都是很常见的。 

在 Objective—C中,搞乱了顺序或者使用了错误字符串标记会造成 app 崩溃。这里,Swift 再次将你从反锁的工作中解放出来,翻译成更少要编写的代码(代码现在已经不容易出错)因为它的对处理文本字符串和数据的内嵌支持。 

6. Swift 更快 

删除遗留下来的C语言约定大大提升了引擎盖之下 Swift 的性能. Swift 代码性能的基准测试一直都瞄向苹果公司所致力于的 Swift 运行 app 逻辑的速度提升。 

根据灵长类动物研究所(Primate Lab)——时下流行的 GeekBench 性能工具的创造者——的调查, 2014 年 12 月中使用曼德尔布罗算法(Mandelbrot algorithm)进行计算密集型任务的性能上,Swift 已经逼近 C++ 的表现了。 

在 2015 年 2 月,灵长类动物研究所发现 Xcode 6.3 测试版提升了 Swift 在 GEMM 算法上的性能 -- 这是一种受制于内存限制的算法,需要对大型数组进行顺序访问 -- 有 1.4 倍. 初始的 FFT 实现 -- 这是一种会对大型数组进行随机访问的受限于内存的算法 -- 拥有 2.6 倍的性能提升。 

通过应用最佳实践,可以观察到更进一步的性能提升, 结果是 FFT 算法上 8.5 倍的性能 (差上 C++ 1.1 倍)。这些改进也使得 Swift 在曼德尔布罗算法上实际超越了 C++ 1.03 倍。 

Swift 在 FFT 和曼德尔布罗算法上几乎能与 C++ 比肩。根据 Primate Labs 的研究发现,GEMM 算法的性能表现说明 Swift 编译器还不能实现 C++ 编译器支持的矢量代码 -- 所以 Swift 的下一个版本可能会比较容易的获得一次性能提升。 

7. 开源项目中更少的名称冲突 

Objective-C 代码中一直令人很困扰的问题就是缺乏对命名空间的正式支持, 它是 C++ 处理文件名冲突的解决方案。当名称冲突发生在 Objective-C 中时,就会是一个连接器错误,会导致 app 无法运行。解决的办法倒是有,可它们都有潜在的隐患。一般的约定是使用两到三个字母前缀来区分编写的 Objective-C 代码, 比方说,通过 非死book 来展现出你自己的代码。 

Swift 提供了隐含的命名空间,允许相同的代码文件存在于多个项目,而不会造成构建失败,或者需要向 NSString (Next Step -- Steve Jobs 被 Apple 炒鱿鱼之后创建的公司) 或者 CGPoint (Core Graphics)这样的名称。最终,Swift 中的这一特性使得开发者更加的有生产力,并且也意味着他们没必要再做 Objective-C 需要的备忘式记忆工作。在简单如 Array,Dictionary 以及 String 这样的名字中你可以看到 Swift 的影响力,而不是脱胎于缺少命名空间的 Objective-C 中的 NSArray、NSDictionary 以及 NSString。 

Swift 的命名空间是基于一份代码文件所属的目标位置。这就意味可以使用命名空间标识来区分出不同的类和值。Swift 中的这个改变很大,它极大的方便了将开发员项目、框架以及库集成到你代码中来的操作。命名空间使得在集成开源项目时,不用担心来自不同软件公司的同名代码 文件会发生冲突。现在 非死book 和苹果公司可以同时使用一个叫做 FlyingCar.swift 的对象代码文件,不会有任何错误或者失败。 

8. Swift 支持动态库 

Swift 中没有受到足够重视的一个最大的问题是静态库向动态库的切换,其在主要发布版(iOS8,iOS7 等等)会被更新。动态库是可以被链接到 app 的可执行代码块。这一特性可以让现有的 Swift 应用可以链接到随着时间推移所产生的更新版本的 Swift 语言。 

开发者将 app 连同库文件一并提交,它们都用开发者证书打上了数字签名,以确保完整性 (你好, NSA)。这就意味着 Swift 可以比 iOS 更快地进化,对于一种现代编程语言而言这是必要的。对库文件的修改可以被全部引入 AppStore 上某个 app 的最新更新中,一起运行起来都如此简单。 

动态库在 iOS 上从未受到支持,直到 Swift 和 iOS 8 的发布,尽管已经在 Mac 获得支持很久了。动态库处在应用可执行文件之外,不过会被包含在从 AppStore 上下载的应用包中。它减小了 app 被加载到内存中的初始大小,因为外部代码只在被用到时才会被链接进来。 

移动应用程序或者是 Apple Watch 上的嵌入式应用所具有的延迟加载能力,将提升应用面向用户的感知性能。这是使得 iOS 生态系统更具感官上的响应性的区别之一。苹果公司原先只专注于运行时加载资料和资源,现在代码的编译和链接也可以在运行时进行。运行时加载减少的等待时 间,直到资源需要被用于展示在屏幕上时,才会被加载进来。 

Swift 中的动态库让编程语言的修改升级比以往更快的传播出去成为了可能。用户不在需要等待指定的 iOS 版本发布才能享受到 Apple 引入 Swift 中的性能和可靠性改进。 

9. Swift Playgrounds 鼓励交互式编码 

Swift 新引入的 Playgrounds 是有经验的开发者的福音。Playgrounds 的灵感来自于苹果公司前雇员 Brett Victor 的工作。Playgrounds 可以让程序员用比如说 5 到 20 行代码来测试一种新的算法或者图形程序,不用去创建一个完整的 iPhone 应用。 

苹果公司已经将内联代码执行操作加入到了 Playgrounds 中,以帮助程序员创建代码块或者编写某种算法时获得反馈。这样的反馈循环可以提升代码编写的速度,因为传统程序员所需要的心智模型已经为 Playground 的数据可视化形式所替代。编程是一个反复的过程,任何可能压力上的减轻或者创造的补充都会使得开发者更具生产力,并能释放出他们的精力来解决更大的问题, 而不是死盯着传统编译器来增加程序员的繁琐细节。 

注意:据我教授新手程序员的经验,Playgrounds 对于入门者而言不会像对有经验的程序员那么有用。如果只是简单的展示 Swift 中一个变量是如何工作的,Playggrounds 显然不能对帮助新手理解对于一个浮点指针变量与一个整型变量的需要。当你要展示一个能记忆你最后在 非死book 新闻提要中的滚动位置时,这种需要才会变得明显。对于新手而言,“为什么”这个问题只能用一个可以运行示例:也就是一个 iPhone 应用,来回答。 

10. Swift 是一个你可以影响的未来 

Objective-C 没有任何出路,你将不会看到它发生改变,我们要感谢 Swift 的引入. 一些 Swift 特性可能会集成到 Objective-C, 但 Objective-C 的 C 语言遗留物还是注定了它只能吸收那么点 Swift 的好东西。 

Swift 向开发者社区提供了一个直接的方式,去影响一门语言,它将会被用于应用的创建,嵌入式系统(如果苹果公司向第三方的嵌入式框架和芯片进行了授权)以及像 Apple Watch 这样的设备. 

苹果公司专注于提供最佳的消费者体验,而且只构建值得注意的功能特性. 随着 Xcode6.3 中 Swfit1.2 的发布,苹果公司已经利用流行的 Apple Bug Reporter 工具修复了数以千计的 bug。支撑 Swfit 开发和改进的团队对于如何提升语言,以更好的支持那些使用 Swift 构建应用和系统的开发社区很感兴趣。 

Swift:更易上手,特性丰富的语言 

从丢弃 Objective-C 赖以构建的传统语言开始,一大堆变化让 Swift 超越了 Objective-C。Apple 并没有丢弃 Cocoa—— 这是他们的用于创建苹果风格体验的 API 和代码库——而是提供了一个完整功能的等价物,使得同支持 Force Touch 或者 Taptic Feedback 这类特性的新 API 交互起来更加简单。 

许多旧的设计决定都旨在让编译器的设计更加容易。Swift 则专注于通过抛弃传统的紧张心理和编码实践,来使得应用开发者的工作更加轻松。随着现代编译器的发展,少量的代码可以表示更多的信息。 

使用 Swift,程序员只要维护原来一半量的代码文件,手动的代码同步工作为零,标点输入出错的概率也远远低于以前 -- 这样就能腾出更多的时间写高质量的代码。通过使用可选类型 —— 一种针对返回或不返回值的编译时安全机制,而返回值是同步操作、网络失效时无效的用户输入以及数据验证错误发生时普遍会遇到的问题。ARC 在 Swift 中对过程式 C 风格的代码,还有苹果公司 Cocoa 框架使用的面向对象代码都进行了统一。 

开发者会发现他们写的 Swift 比较少,而现代的编程语言特性则支持着他们行行代码都保持更多的可读性。随着其不断发展,Swift 会保持整个苹果公司的生态系统在编程领域的先进性,这都要感谢 iOS 和 Swift 中对动态库的支持。开源项目、第三方 SDK 以及框架可以更容易的集成进家居自动化设备以及社交服务中,不会有编译时间的增长。Swift 在某些算法的速度上几乎与 C++ 一样的快,而最新版的 Xcode 6.3 和 Swift 1.2 则在这一起跑线上把目标指向更多的性能优化。 

再加上 playgrounds 和 swift 允许用一个新的方法来开发视觉反馈协助使用内联数据可视化算法程序,让一个较短的反馈回路和图形描述迭代译码过程更容易开始。 

最终,Swift 是一个平易近人的全功能的编程语言,未来将允许开发者不仅构建 app 还支持嵌入式系统比如新的低功耗 apple watch。